Advanced TypeScript Types
Conditional types, mapped types, template literals, and more
What you'll learn
Use conditional types with the ternary syntax for type-level logic
Extract types dynamically with the infer keyword
Build template literal types for string pattern matching
Create recursive types for nested data structures
Leverage discriminated unions for type-safe state machines
Use satisfies operator to validate types without widening
TypeScript's type system is Turing-complete. These advanced patterns unlock powerful abstractions.
Conditional Types
type IsString<T> = T extends string ? "yes" : "no"
type A = IsString<"hello"> // "yes"
type B = IsString<number> // "no"
// Extract return type from a function
type ReturnOf<T> = T extends (...args: unknown[]) => infer R ? R : never
type Num = ReturnOf<() => number> // number
Mapped Types
type Readonly<T> = {
readonly [K in keyof T]: T[K]
}
type Optional<T> = {
[K in keyof T]?: T[K]
}
// Transform all values to strings
type Stringify<T> = {
[K in keyof T]: string
}
Template Literal Types
type EventName = `on${Capitalize<string>}`
// "onClick" | "onChange" | "onSubmit" ...
type Color = "primary" | "secondary"
type Size = "sm" | "md" | "lg"
type Variant = `${Color}-${Size}`
// "primary-sm" | "primary-md" | ...
Next Steps
Key Takeaways
Conditional types enable type-level if/else logic for dynamic type transformations
Template literal types allow string pattern matching and construction at the type level
Recursive types model deeply nested structures like JSON, trees, and linked lists
Discriminated unions combine a literal type property with switch narrowing for exhaustive state handling
The satisfies operator validates a type against a constraint without widening the type