Type guards help the compiler figure out which shape a value has at a given point. When a check succeeds, TypeScript narrows the type so you can access the right properties safely:
function process(value: string | number) {
if (typeof value === 'string') {
return value.toUpperCase(); // ✅ TypeScript knows it's a string
}
return value.toFixed(2); // ✅ TypeScript knows it's a number
}Built-in type guards:
typeof – for primitives ('string', 'number', 'boolean')instanceof – for classes (value instanceof Date)in – for property checks ('name' in obj)Array.isArray() – for arraysCustom type guards:
function isUser(value: unknown): value is User {
return typeof value === 'object' && value !== null && 'id' in value;
}In this category, you'll:
value is Typeswitch statements with discriminated unionsnever type to catch unhandled casesBy the end, you'll be able to narrow any union type safely and teach TypeScript about your own runtime checks.