Need to type guard but instanceof
doesn't work with TypeScript type
s:
type Letter = 'A' | 'B';
const isLetter = (c: any): c is Letter => c instanceof Letter; // Error: 'Letter' only refers to a type, but is being used as a value here.
// Expected usage: Filter via type guard.
isLetter('a'); // Should output true
'foo bar'.split('').filter(c => isLetter(c)); // Should output 'a'
Haven't found similar questions but instanceof
works with classes:
class Car {}
const isCar = (c: any): c is Car => c instanceof Car; // No error
isCar('a'); // false
If instanceof
only works with classes, what is it's equivalent for type
, & how can we type guard using a TypeScript type
?
TS types only exist in the compilation phase, not in runtime.
In a user-defined type guard it is your duty to implement appropriate checks. The check will vary depending on the type of input and output - selecting between a few alternatives is simpler than asserting the shape of completely unknown object.
For your type Letter (union of 'A' and 'B') it is enough to check whether input is A or input is B
const isLetter = (c: any): c is Letter => c == 'A' || c == 'B';
If your union has more members and you dont want to repeat them in union and in type guard:
const letters = ['A', 'B'] as const;
type Letter = typeof letters[number];
const isLetter = (c: any): c is Letter => letters.includes(c);
Note: Classes are preserved at runtime (via prototype chain) - which is why you can use instanceof operator with classes.