TypeScript Advanced Types
In this page:
Intersection Types Overview
An intersection type, written with &, combines multiple types into one that must satisfy every combined type at once, so a value typed as A & B needs all the properties from both A and B rather than being valid if it matches either one.
Example: Intersection Types Overview
type Named = { name: string };
type Aged = { age: number };
type Person = Named & Aged;
const user: Person = { name: "Ravi", age: 25 };
console.log(user);
Discriminated Unions
A discriminated union is a union of object types that share a common literal property, often called kind or status, which TypeScript uses to narrow the union to a specific member inside an if or switch check, giving safe access to that member's unique properties.
Example: Discriminated Unions
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function area(shape: Shape): number {
if (shape.kind === "circle") return Math.PI * shape.radius ** 2;
return shape.side ** 2;
}
console.log(area({ kind: "square", side: 4 }));
Template Literal Types
Template literal types build new string literal types by interpolating other literal or union types inside backticks, similar to JavaScript template strings, so combining two unions like Direction and Side produces every possible dash-joined combination as a type.
Example: Template Literal Types
type Direction = "top" | "bottom";
type Side = "left" | "right";
type Corner = `${Direction}-${Side}`;
const c: Corner = "top-left";
console.log(c);
Recursive Types
A recursive type refers to itself in its own definition, which lets TypeScript describe deeply nested or self-similar structures like JSON values or nested arrays, where a value at any level can itself contain more values of the same shape.
Example: Recursive Types
type Json = string | number | boolean | Json[] | { [key: string]: Json };
const data: Json = { name: "Ravi", tags: ["a", "b"], nested: { active: true } };
console.log(data);
Combining Advanced Type Features
Advanced type features are rarely used in isolation: real-world type definitions often combine intersections, discriminated unions, template literals, and mapped types together to model APIs, state machines, and other structures precisely.
Example: Combining Advanced Type Features
type Event =
| { type: "click"; target: `#${string}` }
| { type: "keydown"; key: string };
function handle(e: Event) {
if (e.type === "click") console.log("Clicked", e.target);
else console.log("Key", e.key);
}
handle({ type: "click", target: "#button" });
Chapter Quiz — Complete all 20 topics to unlock
0/20 topics done
Complete these topics first:
- TypeScript Advanced Types
- Mapped Types
- Conditional Types
- Custom Type Guards
- Assertion Functions
- Control Flow Analysis
- Exhaustiveness Checking
- Satisfies Operator
- Template Literal Types
- Utility Types - Partial
- Utility Types - Required
- Utility Types - Readonly
- Utility Types - Pick
- Utility Types - Omit
- Utility Types - Record
- Utility Types - Exclude and Extract
- Utility Types - NonNullable
- Utility Types - ReturnType
- Utility Types - Parameters
- TypeScript 5 Updates