I'm trying to find a way to pass an object to function in and check it type in a runtime. This is a pseudo code:
function func (obj:any) { if(typeof obj === "A") { // do something } else if(typeof obj === "B") { //do something else } } let a:A; let b:B; func(a);
But typeof
always returns "object"
and I could not find a way to get the real type of a
or b
. instanceof
did not work either and returned the same.
Any idea how to do it in TypeScript?
By default, TypeScript does not verify types at runtime in order to avoid runtime overhead and aggressively optimize runtime performance as a part of its design goals.
Object. getClass() method is used to determine the type of object at run time.
Use the typeof operator to check the type of a variable in TypeScript, e.g. if (typeof myVar === 'string') {} . The typeof operator returns a string that indicates the type of the value and can be used as a type guard in TypeScript.
Use the typeof operator to get the type of an object or variable in JavaScript. The typeof operator also returns the object type created with the "new" keyword. As you can see in the above example, the typeof operator returns different types for a literal string and a string object.
Edit: I want to point out to people coming here from searches that this question is specifically dealing with non-class types, ie object shapes as defined by
interface
ortype
alias. For class types you can use JavaScript'sinstanceof
to determine the class an instance comes from, and TypeScript will narrow the type in the type-checker automatically.
Types are stripped away at compile-time and do not exist at runtime, so you can't check the type at runtime.
What you can do is check that the shape of an object is what you expect, and TypeScript can assert the type at compile time using a user-defined type guard that returns true (annotated return type is a "type predicate" of the form arg is T
) if the shape matches your expectation:
interface A { foo: string; } interface B { bar: number; } function isA(obj: any): obj is A { return obj.foo !== undefined } function isB(obj: any): obj is B { return obj.bar !== undefined } function func(obj: any) { if (isA(obj)) { // In this block 'obj' is narrowed to type 'A' obj.foo; } else if (isB(obj)) { // In this block 'obj' is narrowed to type 'B' obj.bar; } }
Example in Playground
How deep you take the type-guard implementation is really up to you, it only needs to return true or false. For example, as Carl points out in his answer, the above example only checks that expected properties are defined (following the example in the docs), not that they are assigned the expected type. This can get tricky with nullable types and nested objects, it's up to you to determine how detailed to make the shape check.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With