7

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?

Ryan Cavanaugh
  • 209,514
  • 56
  • 272
  • 235

1 Answers1

13

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.

Community
  • 1
  • 1
Ryan Cavanaugh
  • 209,514
  • 56
  • 272
  • 235