TypeScript 模板字面量类型与类型提取
模板字面量类型与 infer 提取是 TypeScript 类型编程的利器,下面梳理核心用法。
模板字面量类型
使用模板字符串语法定义类型约束:
TypeScript
type EventName = "click" | "hover" | "focus";
type EventKey = `on${Capitalize<EventName>}`;
// "onClick" | "onHover" | "onFocus"
type EventMap = {
[K in EventKey]: () => void;
};
const events: EventMap = {
onClick() {},
onHover() {},
onFocus() {}
};
路由路径类型
TypeScript
type Method = "GET" | "POST" | "PUT" | "DELETE";
type Resource = "user" | "product" | "order";
type ApiRoute = `/${Resource}` | `${Method} /${Resource}`;
const route: ApiRoute = "GET /user"; // ✅
// const bad: ApiRoute = "PATCH /user"; // ❌
字符串操作内置工具
| 工具类型 | 说明 |
|---|---|
Uppercase<S> | 转大写 |
Lowercase<S> | 转小写 |
Capitalize<S> | 首字母大写 |
Uncapitalize<S> | 首字母小写 |
TypeScript
type A = Uppercase<"hello">; // "HELLO"
type B = Capitalize<"hello">; // "Hello"
type C = Uncapitalize<"Hello">; // "hello"
模板推断
TypeScript
type Route = `/users/${string}` | `/products/${string}`;
function fetch(route: Route) {}
fetch("/users/123"); // ✅
fetch("/products/456"); // ✅
// fetch("/orders/789"); // ❌
路径参数提取
TypeScript
type ExtractPathParams<T extends string> =
T extends `${string}:${infer Param}/${infer Rest}`
? Param | ExtractPathParams<`/${Rest}`>
: T extends `${string}:${infer Param}`
? Param
: never;
type Params = ExtractPathParams<"/users/:id/posts/:postId">;
// "id" | "postId"
keyof 与 typeof
keyof 获取对象键类型
TypeScript
interface User {
name: string;
age: number;
email: string;
}
type UserKeys = keyof User;
// "name" | "age" | "email"
typeof 获取值类型
TypeScript
const user = { name: "Alice", age: 25 };
type UserType = typeof user;
// { name: string; age: number; }
const STATUS = { OK: 0, ERROR: 1 } as const;
type StatusType = typeof STATUS;
// { readonly OK: 0; readonly ERROR: 1; }
keyof + typeof 枚举对象键
TypeScript
const COLORS = {
RED: "#FF0000",
GREEN: "#00FF00",
BLUE: "#0000FF"
} as const;
type ColorName = keyof typeof COLORS;
// "RED" | "GREEN" | "BLUE"
type ColorValue = typeof COLORS[ColorName];
// "#FF0000" | "#00FF00" | "#0000FF"
索引访问类型
使用 T[K] 语法通过键名索引访问对象属性类型:
TypeScript
interface User {
name: string;
age: number;
email: string;
}
type NameType = User["name"]; // string
type Keys = "name" | "age";
type Types = User[Keys]; // string | number
数组索引访问
TypeScript
type Arr = [string, number, boolean];
type First = Arr[0]; // string
type Last = Arr[2]; // boolean
函数参数访问
TypeScript
interface Events {
onClick: (e: MouseEvent) => void;
onHover: (e: MouseEvent) => void;
}
type ClickHandler = Events["onClick"];
// (e: MouseEvent) => void
Infer 类型提取
在条件类型中使用 infer 推断并提取类型:
提取函数返回值
TypeScript
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
function getUser() { return { id: 1, name: "Alice" }; }
type User = ReturnType<typeof getUser>;
提取 Promise 值
TypeScript
type Awaited<T> = T extends Promise<infer V> ? Awaited<V> : T;
type UserPromise = Promise<Promise<{ id: string }>>;
type User = Awaited<UserPromise>;
// { id: string }
提取数组元素
TypeScript
type ElementType<T> = T extends (infer E)[] ? E : T;
type Arr = string[];
type Item = ElementType<Arr>; // string
提取元组首尾
TypeScript
type First<T extends any[]> = T extends [infer F, ...any[]] ? F : never;
type Last<T extends any[]> = T extends [...any[], infer L] ? L : never;
type A = First<[string, number, boolean]>; // string
type B = Last<[string, number, boolean]>; // boolean
提取构造函数参数
TypeScript
type ConstructorParameters<T extends new (...args: any[]) => any> =
T extends new (...args: infer P) => any ? P : never;
class User {
constructor(public name: string, public age: number) {}
}
type Params = ConstructorParameters<typeof User>;
// [name: string, age: number]
要点总结
- 模板字面量类型用模板字符串定义类型约束,支持字符串操作
keyof T获取对象所有键名的联合类型typeof T获取变量/常量的类型T[K]索引访问属性类型,支持联合键infer在条件类型中推断并提取类型,常用于函数返回值/Promise/数组元素- 模板推断可结合
infer提取路径参数等复杂类型
📝 发现内容有误?点击此处直接编辑