Reading — step 1 of 5
Learn
~2 min readBranded Types and Guards
A type guard is a runtime check that narrows the type. Built-ins like typeof, instanceof, in work for primitives and classes.
For your own types, define a type predicate:
function isString(x: unknown): x is string {
return typeof x === 'string';
}
function process(input: unknown) {
if (isString(input)) {
console.log(input.toUpperCase()); // narrowed to string
}
}
The return type x is string tells TypeScript: "if this returns true, narrow x to string".
For discriminated unions — built-in narrowing:
type Shape =
| { kind: 'circle'; radius: number }
| { kind: 'square'; side: number };
function area(s: Shape): number {
if (s.kind === 'circle') {
return Math.PI * s.radius ** 2; // narrowed to circle variant
}
return s.side ** 2; // narrowed to square
}
Custom guards for complex shapes:
interface User {
name: string;
age: number;
}
function isUser(x: unknown): x is User {
return typeof x === 'object'
&& x !== null
&& typeof (x as any).name === 'string'
&& typeof (x as any).age === 'number';
}
const data: unknown = JSON.parse(input);
if (isUser(data)) {
console.log(data.name); // narrowed
}
Useful for parsing JSON safely.
asserts keyword — narrows AND throws if the assertion fails:
function assertIsUser(x: unknown): asserts x is User {
if (!isUser(x)) {
throw new TypeError('not a user');
}
}
function handle(data: unknown) {
assertIsUser(data);
// Past here, data is User — TypeScript knows
console.log(data.name);
}
in operator narrowing:
function describe(animal: { name: string } | { species: string }) {
if ('name' in animal) {
// narrowed to { name: string }
} else {
// narrowed to { species: string }
}
}
Exhaustiveness pattern with never:
function area(s: Shape): number {
switch (s.kind) {
case 'circle': return Math.PI * s.radius ** 2;
case 'square': return s.side ** 2;
default:
const _exhaustive: never = s; // compile error if Shape grows
return _exhaustive;
}
}
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…