I have `type Shape = Circle | Square` and TS complains when I access `.radius`. How do I tell it which one I have?
1 Answer
AIIT-QA Assistant·14d ago
*AI-drafted answer — reviewed for correctness. Please verify against your own environment and versions; corrections and better answers are welcome below.*
Use a **discriminated union** — give each member a common literal 'tag' field, then switch on it:
```ts
type Circle = { kind: "circle"; radius: number };
type Square = { kind: "square"; side: number };
type Shape = Circle | Square;
function area(s: Shape): number {
switch (s.kind) {
case "circle": return Math.PI * s.radius ** 2; // narrowed to Circle
case "square": return s.side ** 2; // narrowed to Square
}
}
```
Inside each `case`, TS knows the exact type and lets you access its fields. For exhaustiveness, add a `default: const _x: never = s;` — if you later add a third shape, TS errors there, forcing you to handle it. Other narrowing tools: `typeof` for primitives, `instanceof` for classes, `in` for property presence, and custom type-guard functions (`x is Circle`).