In JavaScript, you can use typeof
keyword to check the type of values:
const fruit = 'apple';
console.log(typeof fruit);
// Output: 'string'
const year = 2022;
console.log(typeof year);
// Output: 'number'
const isOpen = true;
console.log(typeof isOpen);
// Output: 'boolean'
const person = {
name: 'Thomas Anderson',
age: 32,
};
console.log(typeof person);
// Output: 'object'
So if you want check a value is a certain type, you can use the typeof
keyword:
const fruit = 'apple';
if (typeof fruit === 'string') {
console.log(`${fruit} is a string`);
}
const year = 2022;
if (typeof year === 'number') {
console.log(`${year} is a number`);
}
But, if you want to check a value is a certain type in TypeScript, the typeof
keyword doesn't work the same way it works in the JavaScript examples above.
type Fruit = 'apple' | 'orange' | 'banana';
const myFruit = 'apple';
// This will NOT work ❌
if (typeof myFruit === 'Fruit') {
console.log(`${myFruit} is a fruit`);
}
You cannot use the typeof
keyword at run-time to check for TypeScript types, because TypeScript removes type annotations, interfaces, type aliases, and other type system constructs during compilation.
So, how can you check if myFruit
is the type of Fruit
?
Step 1 — Type Inference
Define a Fruit
type as an array of literal values and TypeScript will infer types from the values:
const fruit = ['apple', 'orange', 'banana'] as const;
type Fruit = (typeof fruit)[number];
Step 2 — Type Guard
Use a user-defined type guard to check against your custom type:
const fruit = ['apple', 'orange', 'banana'] as const;
type Fruit = (typeof fruit)[number];
const isFruit = (x: any): x is Fruit => fruit.includes(x);
isFruit()
function will check if its argument is in the fruit
array, and if so, it will narrow its argument to Fruit
:
const fruit = ['apple', 'orange', 'banana'] as const;
type Fruit = (typeof fruit)[number];
const isFruit = (x: any): x is Fruit => fruit.includes(x);
const myFruit = 'apple';
// This will work ✅
if (isFruit(myFruit)) {
console.log(`${myFruit} is a type of Fruit`);
} else {
console.log(`${myFruit} is NOT a type of Fruit`)
}
// Output: "apple is a typeof Fruit"
Now we can also see our type checking working, when we have a value that is not a part of our fruit array:
const fruit = ['apple', 'orange', 'banana'] as const;
type Fruit = (typeof fruit)[number];
const isFruit = (x: any): x is Fruit => fruit.includes(x);
const myFruit = 'mango';
// This will work ✅
if (isFruit(myFruit)) {
console.log(`${myFruit} is a type of Fruit`);
} else {
console.log(`${myFruit} is NOT a type of Fruit`)
}
// Output: "mango is NOT a typeof Fruit"
// (In reality mango is a fruit, but since it is not
// a part of our fruit array, it is NOT a type Fruit)
In Summary
TypeScript only exists is the compile-time and it is completely discarded in the run-time.
This means you CANNOT use typeof
keyword to check for custom types.
Instead, you can use type inference
together with a type guard
to check against a custom type.
Thank you for reading! ✌️
You can follow me on Twitter
Top comments (0)