snippettypescriptModeratepending
TypeScript assertion functions and type narrowing
Viewed 0 times
assertion functiontype narrowingassertstype guardvalidation
Problem
Need to validate data at runtime and have TypeScript understand the validated type without explicit casting.
Solution
Assertion functions narrow types after validation:
// Assertion function: throws if condition fails
function assertDefined<T>(val: T | null | undefined, msg?: string): asserts val is T {
if (val === null || val === undefined) {
throw new Error(msg ?? 'Value is not defined');
}
}
// After calling, TypeScript knows val is T
const user: User | null = getUser();
assertDefined(user, 'User not found');
console.log(user.name); // TypeScript knows user is User here
// Assert with type predicate
function assertIsString(val: unknown): asserts val is string {
if (typeof val !== 'string') {
throw new TypeError(`Expected string, got ${typeof val}`);
}
}
// Complex assertion for API responses
interface ApiResponse {
status: number;
data: Record<string, unknown>;
}
function assertValidResponse(res: unknown): asserts res is ApiResponse {
if (typeof res !== 'object' || res === null) {
throw new Error('Response is not an object');
}
if (!('status' in res) || typeof (res as any).status !== 'number') {
throw new Error('Missing or invalid status');
}
if (!('data' in res) || typeof (res as any).data !== 'object') {
throw new Error('Missing or invalid data');
}
}
// Type guard (returns boolean instead of throwing)
function isUser(val: unknown): val is User {
return typeof val === 'object' && val !== null && 'name' in val && 'email' in val;
}
if (isUser(data)) {
console.log(data.name); // Narrowed to User
}Why
Assertion functions bridge runtime validation and compile-time type checking. After an assertion, TypeScript narrows the type without unsafe casts.
Context
TypeScript code validating external data (API responses, user input)
Revisions (0)
No revisions yet.