TypeScript 实用类型:实战参考
TypeScript 自带一套内置的实用类型,用于转换现有类型。这些类型让你能从已有类型派生出新类型,无需重复定义类型,从而减少维护负担并保持代码库 DRY。

对象转换类型
Partial<T>
将所有属性变为可选。
interface User {
id: number;
name: string;
email: string;
role: 'admin' | 'user';
}
// 所有字段可选——适用于更新负载
type UserUpdate = Partial<User>;
function updateUser(id: number, changes: Partial<User>) {
// changes 可以包含 User 字段的任意子集
}
updateUser(1, { name: 'Alice' }); // ✅
updateUser(1, { email: 'a@b.com', role: 'admin' }); // ✅
Required<T>
将所有属性变为必填(与 Partial 相反)。
interface Config {
timeout?: number;
retries?: number;
baseUrl?: string;
}
// 初始化后所有字段必填
type ResolvedConfig = Required<Config>;
function resolveConfig(input: Config): ResolvedConfig {
return {
timeout: input.timeout ?? 5000,
retries: input.retries ?? 3,
baseUrl: input.baseUrl ?? 'https://api.example.com',
};
}
Readonly<T>
将所有属性变为只读(不可重新赋值)。
const config: Readonly<Config> = {
timeout: 5000,
retries: 3,
baseUrl: 'https://api.example.com',
};
config.timeout = 1000; // ❌ 错误:无法分配到 'timeout'(只读)
Pick<T, K>
创建一个仅包含选定键的类型。
interface User {
id: number;
name: string;
email: string;
passwordHash: string;
createdAt: Date;
}
// 面向公众的用户——排除敏感字段
type PublicUser = Pick<User, 'id' | 'name' | 'email'>;
// 类型:{ id: number; name: string; email: string }
function getPublicProfile(user: User): PublicUser {
return { id: user.id, name: user.name, email: user.email };
}
Omit<T, K>
创建一个移除了指定键的类型。
// 移除敏感和自动生成字段,用于创建输入
type CreateUserInput = Omit<User, 'id' | 'passwordHash' | 'createdAt'>;
// 类型:{ name: string; email: string }
function createUser(input: CreateUserInput): User {
return {
...input,
id: generateId(),
passwordHash: hashPassword(input.email),
createdAt: new Date(),
};
}
Pick vs Omit: 当你需要大型类型的一小部分时使用 Pick;当你需要类型的大部分字段但排除少数几个时使用 Omit。

Record<K, V>
创建一个对象类型,键为 K 类型,值为 V 类型。
// 从字符串键到数字的映射
type ScoreMap = Record<string, number>;
const scores: ScoreMap = { alice: 95, bob: 87 };
// 将枚举值映射到配置对象
type EnvironmentConfig = Record<'dev' | 'staging' | 'prod', {
apiUrl: string;
debug: boolean;
}>;
const envConfig: EnvironmentConfig = {
dev: { apiUrl: 'http://localhost:3000', debug: true },
staging: { apiUrl: 'https://staging.api.example.com', debug: true },
prod: { apiUrl: 'https://api.example.com', debug: false },
};
// 更严格的约束:键必须是有效的 HTTP 方法
type HttpMethodHandlers = Record<'GET' | 'POST' | 'PUT' | 'DELETE', Function>;
联合/交叉类型辅助
Exclude<T, U>
从联合类型 T 中移除可赋值给 U 的类型。
type Status = 'pending' | 'active' | 'deleted' | 'banned';
// 移除管理状态
type UserFacingStatus = Exclude<Status, 'deleted' | 'banned'>;
// 类型:'pending' | 'active'
type NonNullableString = Exclude<string | null | undefined, null | undefined>;
// 类型:string
Extract<T, U>
仅保留联合类型 T 中可赋值给 U 的类型(与 Exclude 相反)。
type Events = 'click' | 'focus' | 'blur' | 'keydown' | 'keyup';
// 仅键盘事件
type KeyboardEvents = Extract<Events, 'keydown' | 'keyup' | 'keypress'>;
// 类型:'keydown' | 'keyup'
// 从联合类型中提取对象类型
type Shape = { kind: 'circle'; radius: number } | { kind: 'square'; side: number } | string;
type ShapeObject = Extract<Shape, object>;
// 类型:{ kind: 'circle'; radius: number } | { kind: 'square'; side: number }
NonNullable<T>
从类型中移除 null 和 undefined。
type MaybeString = string | null | undefined;
type DefiniteString = NonNullable<MaybeString>;
// 类型:string
function processName(name: string | null): string {
const safe: NonNullable<typeof name> = name ?? 'Anonymous';
return safe.toUpperCase();
}
函数相关类型

ReturnType<T>
提取函数类型的返回类型。
function fetchUser(id: number) {
return { id, name: 'Alice', email: 'alice@example.com' };
}
type FetchedUser = ReturnType<typeof fetchUser>;
// 类型:{ id: number; name: string; email: string }
// 也适用于异步函数
async function getConfig() {
return { timeout: 5000, debug: false };
}
type Config = Awaited<ReturnType<typeof getConfig>>;
// 类型:{ timeout: number; debug: boolean }
// 注意:Awaited 会展开 Promise
Parameters<T>
将函数参数提取为元组类型。
function createEvent(name: string, date: Date, attendees: number) {
// ...
}
type CreateEventParams = Parameters<typeof createEvent>;
// 类型:[name: string, date: Date, attendees: number]
// 对包装函数很有用
function createEventWithLogging(...args: Parameters<typeof createEvent>) {
console.log('Creating event:', args[0]);
return createEvent(...args);
}
ConstructorParameters<T>
提取构造函数参数。
class HttpClient {
constructor(baseUrl: string, timeout: number, headers: Record<string, string>) {}
}
type ClientConfig = ConstructorParameters<typeof HttpClient>;
// 类型:[baseUrl: string, timeout: number, headers: Record<string, string>]
InstanceType<T>
提取构造函数的实例类型。
class ApiClient {
get(url: string) { return fetch(url); }
post(url: string, body: unknown) { return fetch(url, { method: 'POST' }); }
}
type Client = InstanceType<typeof ApiClient>;
// 类型:ApiClient
// 对工厂模式很有用
function createClient(): InstanceType<typeof ApiClient> {
return new ApiClient();
}
组合实用类型
实际类型通常组合多个实用类型:
interface Article {
id: string;
title: string;
content: string;
authorId: string;
publishedAt: Date;
updatedAt: Date;
tags: string[];
}
// 创建输入:无自动生成字段
type CreateArticleInput = Omit<Article, 'id' | 'publishedAt' | 'updatedAt'>;
// 更新输入:除 id 外所有字段可选
type UpdateArticleInput = Partial<Omit<Article, 'id'>> & Pick<Article, 'id'>;
// 文章预览:仅显示字段
type ArticlePreview = Pick<Article, 'id' | 'title' | 'authorId' | 'publishedAt' | 'tags'>;
// 深度 Partial(实用类型默认不深度处理)
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
模板字面量类型(高级)
// 从事件名称生成事件处理函数名称
type EventNames = 'click' | 'focus' | 'blur';
type HandlerNames = `on${Capitalize<EventNames>}`;
// 类型:'onClick' | 'onFocus' | 'onBlur'
// 生成 getter/setter 对
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
interface User { name: string; age: number; }
type UserGetters = Getters<User>;
// 类型:{ getName: () => string; getAge: () => number }
快速参考
| 实用类型 | 作用 |
|---|---|
Partial<T> |
所有属性可选 |
Required<T> |
所有属性必填 |
Readonly<T> |
所有属性只读 |
Pick<T, K> |
仅保留 K 键 |
Omit<T, K> |
移除 K 键 |
Record<K, V> |
键为 K、值为 V 的对象 |
Exclude<T, U> |
从联合类型 T 中移除 U |
Extract<T, U> |
仅保留联合类型 T 中的 U |
NonNullable<T> |
移除 null/undefined |
ReturnType<T> |
函数返回类型 |
Parameters<T> |
函数参数类型 |
Awaited<T> |
展开 Promise 类型 |
→ 使用 JSON Viewer 查看和探索复杂的 JSON 数据结构。