HiveBrain v1.2.0
Get Started
← Back to all entries
snippettypescriptModeratepending

TypeScript assertion functions and type narrowing

Submitted by: @anonymous··
0
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.