
Typescript under the hood is Javascript and Javascript is weird. Typescript comes with the premise of bringing some sanity to Javascript by using a typesystem which catches type bugs at compile-time instead of runtime. Explicity writing types and not using type coercion takes almost no extra time but gives us the benefit of having a better tooling during development and also having a better certaintity on shipping bug-free software.
A Case for Typescript
Even the creator of Javascript, Brendan Eich, regrets rushing type coercion and thus making it slopy. If you are not familar with the term type coercion, I want to quickly explain to you what it is about:
Type coercion in Javascript allows to make implicit typecasts which allows for doing operations on variables of different types. Note, that every Javascript variable has a type even though it is not specified excplicitly.
Due too type coercion, unexpected things like these can actually happen:
const nope = Array(10).join("nope" - 1) + " Batman!";console.log(nope); // --> NaNNaNNaNNaNNaNNaNNaNNaNNaN Batman!const a = [ 1, 2, 3 ];
const b = [ 1, 2, 3 ];
console.log(a + b); //-> 1,2,31,2,3
This makes my point clear that we really have the need for Typescript. And to be honest, Typescript is the best thing that ever happend to Javascript, but it still cannot solve every problem Javascript has because of one good reason:
Typescript transpiles to Javascript which means that Typescript code is never executed but always converted to Javascript. On the one hand this means that we do not have any access to the Typescript types at runtime, but on the other hand it allows an easy migration from Javascript to Typescript since it can be done gradually.
Typeof
In object oriented programming typeguards, such as typeof or instanceof, are used to determine the type or the class of a variable. This is especially useful with polymorphism (allows to pulgin concrete subclasses into superclass definitions at runtime) to build something like a factory pattern which creates a certain object depending on some inner logic:
Gotcha! This is the first catch. You probably have expected the type of x to be Small and the type of y to be Big since it is common OOP practice. There are two things to know:
- There is no Typescript at runtime. typeof() executes at runtime and therefore has no access to the Typescript type definitions.
2. Classes in Javascript are basically just a lot of syntactic sugar for just a constructor function and an object with a certain prototype.
Note, that if typeof is used on an interface the output is still object, since interfaces do not transpile to anything in javascript. Every variable that has an interface type is basically simply a prototype object.
Instanceof
Instanceof on the other hand is indeed very useful for us because it actually can determine concrete classes by looking if an object prototype inherits from the prototype of a specified object definition.
For example, p instanceof Person would look if p.prototype inherits Person.protoype. Note, that I purposefully used the word inherit since an object prototype is chained with all its super/base prototypes.
For example, almost all prototypes inherit from Object.prototype
In this example we can see that x’s protoype chains Small, BaseClass, Object in exactly that order. Therfore, an instanceof on those classes returns true, wherase an instanceof on Big returns false.
By doing some Javascript magic we can manually change the prototype of the class Small to Big.prototype. This way an instanceof on a variable created with the Small constructor is now going to be an instance of Small, BaseClass, Object, but also Big because Big and Small share the same prototype now.
This means that as long as the prototype is the same, instanceof will return true.
Interfaces
This short section is here to explicity state that interfaces can neither be used with typeof or instanceof in a senseful way because interfaces are removed completey when Typescript is transpiled to Javascript because the hold nothing but variable and type definitions. Concluding that an interface only lives in the Typescript space and therefore does not exist at runtime typeof and instanceof, which on the other hand are executed in runtime, are not useful.
Conclusion
Typescript is great but since it does not live in the runtime, we still have to mind Javascript functions and even though types are defined in Typescript, the typeof and instanceof function have no connection to Typescript at all. You learned that typeof is not very useful to check if an object inherits from a class, but instanceof can help in that case. Interfaces should not be used with either typeof, nor instanceof.