TypeScriptFrontend
Advanced TypeScript Type Gymnastics
2024-02-2010 min
分享
Beyond Basic Types
Most TypeScript users stop at interfaces and generics. But the type system is a full programming language — conditional types, mapped types, and template literals let you encode complex invariants at compile time.
Conditional Types
Think of them as ternary operators for types:
type IsString<T> = T extends string ? true : false;
type A = IsString<"hello">; // true
type B = IsString<42>; // false
Mapped Types
Transform every property in a type:
type Readonly<T> = {
readonly [K in keyof T]: T[K];
};
type Optional<T> = {
[K in keyof T]?: T[K];
};
Template Literal Types
String manipulation at the type level:
type EventName<T extends string> = `on${Capitalize<T>}`;
type ClickEvent = EventName<"click">; // "onClick"
type FocusEvent = EventName<"focus">; // "onFocus"
A Practical Example
Here's a type-safe event emitter:
type EventMap = {
click: { x: number; y: number };
focus: { target: string };
};
type Handler<T> = (payload: T) => void;
class Emitter<E extends Record<string, unknown>> {
on<K extends keyof E>(event: K, handler: Handler<E[K]>): void {
// implementation
}
}
const emitter = new Emitter<EventMap>();
emitter.on("click", ({ x, y }) => {}); // fully typed
When to Stop
Type gymnastics are powerful but have a cost: readability. If a colleague can't understand your type in 30 seconds, simplify it. Types serve developers, not the other way around.
评论 (0)
还没有评论,来说点什么吧。