← All sheets

TypeScript

Types, generics, narrowing and the utility types worth knowing.

Basic types

let name: string = 'Ada';
let count: number = 42;
let isActive: boolean = true;
let tags: string[] = ['a', 'b'];
let pair: [string, number] = ['x', 1];
let anything: unknown;        // safer than any
function fail(): never { throw new Error(); }

Type vs interface

type Point = { x: number; y: number };
interface User { id: string; name: string }

interface Admin extends User { role: 'admin' }
type Status = 'idle' | 'loading' | 'done';   // unions: type only

Narrowing

function format(value: string | number) {
  if (typeof value === 'string') {
    return value.toUpperCase();
  }
  return value.toFixed(2);
}

if ('role' in user) { /* Admin */ }
if (error instanceof Error) { /* Error */ }

function isUser(value: unknown): value is User {
  return typeof value === 'object' && value !== null && 'id' in value;
}

Generics

function first<T>(items: T[]): T | undefined {
  return items[0];
}

function getProperty<T, K extends keyof T>(object: T, key: K): T[K] {
  return object[key];
}

type ApiResponse<T> = { data: T; error?: string };

Utility types

Type Result
Partial<T> All properties optional
Required<T> All properties required
Readonly<T> All properties readonly
Pick<T, 'a' | 'b'> Only the listed keys
Omit<T, 'a'> All keys except the listed ones
Record<K, V> Object with keys K and values V
Exclude<U, X> Remove X from union U
Extract<U, X> Keep only X from union U
NonNullable<T> Remove null and undefined
ReturnType<typeof fn> Return type of a function
Parameters<typeof fn> Parameter tuple of a function
Awaited<T> Unwrap a Promise type

Const objects as source of truth

const ROLES = {
  admin: 'Administrator',
  editor: 'Editor',
  viewer: 'Viewer',
} as const;

type Role = keyof typeof ROLES;               // 'admin' | 'editor' | 'viewer'
type RoleLabel = (typeof ROLES)[Role];
const roleKeys = Object.keys(ROLES) as Role[];

Operators

Syntax Meaning
keyof T Union of keys of T
typeof value Type of a value
T[K] Indexed access type
value as T Type assertion
value! Non-null assertion
value satisfies T Check type without widening
T extends U ? X : Y Conditional type
{ [K in keyof T]: X } Mapped type
`prefix-${T}` Template literal type