TypeScript - Narrowing & Type Guards

typeof / instanceof / in

function printLen(x: string | any[]) {
  if (typeof x === 'string') return x.length; // string
  return x.length; // any[]
}

function isDate(x: unknown): x is Date { return x instanceof Date }

function hasId(x: any): x is { id: string } { return 'id' in x }

Discriminated unions

type Done = { state: 'done'; value: number };
type Loading = { state: 'loading' };

type Result = Done | Loading;

function render(r: Result) {
  if (r.state === 'done') return r.value; // r is Done
  return 'Loading...';
}

Exhaustive checks

function exhaustive(x: never): never { throw new Error('unreachable') }