Different shapes, one type
A payment can be cash (amount), card (amount, last four digits) or eSewa (amount, wallet ID). Each case carries different data. A discriminated union models this perfectly — and TypeScript makes sure you handle every case.
A shared "kind" field
type Payment =
| { kind: "cash"; amount: number }
| { kind: "card"; amount: number; last4: string }
| { kind: "wallet"; amount: number; walletId: string };
function receipt(p: Payment): string {
switch (p.kind) {
case "cash":
return `Cash Rs ${p.amount}`;
case "card":
return `Card ••••${p.last4}`;
case "wallet":
return `Wallet ${p.walletId}`;
}
}
console.log(receipt({ kind: "card", amount: 900, last4: "4242" }));type Shape = { kind: "circle"; r: number } | { kind: "square"; side: number } | { kind: "triangle"; base: number; h: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle": return Math.PI * s.r ** 2;
case "square": return s.side ** 2;
default: {
const unhandled: never = s;
return unhandled;
}
}
}