Lessons in this course (9)

3. Functions, unions and narrowing

Basic★ Must knowLesson 3 of 9
typescript
function total(lines: { qty: number; price: number }[], discount = 0): number {
  return lines.reduce((s, l) => s + l.qty * l.price, 0) * (1 - discount);
}
const greet = (name: string, title?: string) => `Hello ${title ?? ""} ${name}`;

function format(value: string | number | Date): string {
  if (typeof value === "string") return value.trim();       // narrowed to string
  if (typeof value === "number") return value.toFixed(2);   // narrowed to number
  return value.toISOString();                               // must be Date
}

// Discriminated union + exhaustive check
type Shape = { kind: "circle"; r: number } | { kind: "rect"; w: number; h: number };
function area(s: Shape): number {
  switch (s.kind) {
    case "circle": return Math.PI * s.r ** 2;
    case "rect":   return s.w * s.h;
    default: { const never: never = s; return never; }   // compile error if a new kind is added
  }
}

// Custom type guard
function isOrder(x: unknown): x is Order {
  return typeof x === "object" && x !== null && "id" in x && "lines" in x;
}

Narrowing tools: typeof, instanceof, in, equality checks, truthiness, discriminant property, type predicates (x is T), assertion functions (asserts x is T).