Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I compare `typeof x` to "null" or "MyClass" in TypeScript?

Tags:

typescript

I wrote some code to do some runtime type tests:

var x = window.opener;
if (typeof x === 'null') {
  // Do something
}
var y = getSomething();
if (typeof y === 'MyClass') {
  // ...
} else if (typeof y === 'array') {
  // ...
}

I got this error on all the if expressions:

error TS2365: Operator '===' cannot be applied to types '"string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"' and '"null"'.

Is this a TypeScript bug? Why doesn't it allow me to use typeof like I want to?

like image 542
Ryan Cavanaugh Avatar asked Feb 08 '17 00:02

Ryan Cavanaugh


1 Answers

This isn't what typeof does!

The typeof operator takes an expression and returns one of the following values*:

  • "string"
  • "number"
  • "boolean"
  • "symbol"
  • "undefined"
  • "object"
  • "function"

You will not see typeof produce values like "null", "Array", or the name of a user-defined class. Note that typeof null is "object" for sad reasons.

Oops! What do I do instead?

So you thought typeof was cooler than it was. Oh well!

  • To test for null, use expr === null. You can use the idiomatic expr == null to test for undefined and null if your coworkers let you get away with using ==
  • To test for an array, use Array.isArray(expr). Note that some things you expect to be arrays, like document.getElementsByTagName("div"), aren't (getElementsByTagName returns a NodeList), so be careful
  • To test for a class type use expr instanceof ClassName

I got 99 problems and IE8 is one of them

If you are really sure that you have an object and runtime combination that produces a different value (as in, you actually tested it, and it really did produce some other string), use a type assertion on either side of the test:

if (typeof x === <string>"magicthinger") {

* In ancient browsers (IE8) when querying typeof of some exotic browser objects, you might get other values, but no modern JavaScript engine does this.

like image 197
Ryan Cavanaugh Avatar answered Jan 03 '23 10:01

Ryan Cavanaugh