What are user-defined type guards and assertion functions?
Take a moment.
Say your answer out loud or write it down first — retrieval is what makes it stick. Reveal when you're ready.
Short answer
A type guard is a boolean function with a value is Type return signature — inside if branches TypeScript narrows accordingly. An assertion function (asserts value is Type) throws when invalid and narrows everything after the call.
Detailed explanation
Runtime data arrives untyped: JSON.parse, API responses, form input. Type guards bridge runtime checks and compile-time knowledge. A guard like function isUser(v: unknown): v is User { return typeof v.id === 'number' && ... } performs actual validation; calling it in an if gives narrowed flow in both branches (else branch excludes User). Guards compose with Array.prototype.filter using type predicates too. Assertion functions invert control: validateOrThrow(user): asserts user is User — execution continues only if valid, so following code narrows without an if. They require explicit return/break discipline in some call positions. Guards should genuinely verify structure (not lie via always-true), and libraries like Zod generate guards from schemas — mention schema-validation integration for bonus points since it eliminates hand-written drift between validator and type.
Example
interface ApiError { status: number; message: string }
function isApiError(e: unknown): e is ApiError {
return typeof e === 'object' && e !== null
&& 'status' in e && 'message' in e;
}
try { await api.call(); }
catch (err: unknown) {
if (isApiError(err)) showToast(err.message); // err: ApiError here
else throw err;
}
function assertDefined<T>(v: T | undefined): asserts v is T {
if (v === undefined) throw new Error('Missing value');
}Interview tip
Show both forms back-to-back (is vs asserts), then connect to Zod/Valibot — 'guards derived from one schema' answers where this question always leads.
Common mistakes
- Writing guards that don't actually validate anything.
- Confusing
v is Twith returning a plain boolean.