1. Required<T> 类型
Required<T> 是 TypeScript 内置的泛型类型,它会将对象类型 T 的所有属性变为必需的,即使原本某些属性是可选的。
示例
typescript
CopyEdit
interface User {
name: string;
age?: number; // 可选属性
}
type RequiredUser = Required<User>;
const user: RequiredUser = {
name: 'John',
age: 25, // 现在 `age` 是必需的
};
- 解释:在上面的例子中,
User接口中的age属性是可选的。通过使用Required<User>,生成了一个新类型RequiredUser,使得age成为了必需属性。
源代码
Required 类型实际上是通过映射类型实现的,它将对象的所有可选属性转换为必需的:
typescript
CopyEdit
type Required<T> = {
[P in keyof T]-?: T[P]; // -? 确保每个属性都变成必需的
};
2. Partial<T> 类型
Partial<T> 是与 Required<T> 相对的辅助类型,它将类型 T 的所有属性变为 可选。
示例
typescript
CopyEdit
interface User {
name: string;
age: number;
}
type PartialUser = Partial<User>;
const user: PartialUser = {
name: 'John', // `age` 是可选的
};
- 解释:在上面的例子中,
Partial<User>将User类型的所有属性变为可选的。
源代码
Partial<T> 类型通过映射类型将对象的所有属性变成可选:
typescript
CopyEdit
type Partial<T> = {
[P in keyof T]?: T[P]; // ? 表示每个属性变为可选的
};
3. Readonly<T> 类型
Readonly<T> 将类型 T 中的所有属性变为 只读,即不能修改这些属性。
示例
typescript
CopyEdit
interface User {
name: string;
age: number;
}
type ReadonlyUser = Readonly<User>;
const user: ReadonlyUser = {
name: 'John',
age: 25,
};
// user.age = 30; // 错误:不能修改只读属性
- 解释:在上面的例子中,
Readonly<User>将User中的所有属性变为只读,意味着你不能再修改这些属性。
源代码
Readonly<T> 类型通过映射类型将所有属性变为只读:
typescript
CopyEdit
type Readonly<T> = {
readonly [P in keyof T]: T[P]; // readonly 表示每个属性变为只读
};
4. Record<K, T> 类型
Record<K, T> 是一个内置的辅助类型,它用来构造一个对象类型,该对象的键是 K,值是 T。常用于通过指定一组键和值类型,构造一个对象类型。
示例
typescript
CopyEdit
type UserRoles = 'admin' | 'user' | 'guest';
type UserPermissions = Record<UserRoles, boolean>;
const permissions: UserPermissions = {
admin: true,
user: false,
guest: true,
};
- 解释:在上面的例子中,
Record<UserRoles, boolean>构造了一个对象类型,其中UserRoles的每个值(admin、user、guest)都是对象的键,且每个键的值都是boolean类型。
5. Pick<T, K> 类型
Pick<T, K> 类型从类型 T 中选择一组属性 K,生成一个新的类型。K 可以是 T 的键的子集。
示例
typescript
CopyEdit
interface User {
name: string;
age: number;
address: string;
}
type NameAndAge = Pick<User, 'name' | 'age'>;
const user: NameAndAge = {
name: 'John',
age: 25,
};
- 解释:在上面的例子中,
Pick<User, 'name' | 'age'>从User类型中提取了name和age属性,生成了一个新类型NameAndAge。
6. Omit<T, K> 类型
Omit<T, K> 类型是 Pick 的反向操作,它从类型 T 中去除属性 K,生成一个新的类型。
示例
typescript
CopyEdit
interface User {
name: string;
age: number;
address: string;
}
type UserWithoutAddress = Omit<User, 'address'>;
const user: UserWithoutAddress = {
name: 'John',
age: 25,
};
- 解释:在上面的例子中,
Omit<User, 'address'>从User类型中去除了address属性,生成了一个新类型UserWithoutAddress。
7. Exclude<T, U> 类型
Exclude<T, U> 从类型 T 中排除掉类型 U 中的所有成员,生成一个新的类型。
示例
typescript
CopyEdit
type AllNumbers = number | string | boolean;
type OnlyNumbers = Exclude<AllNumbers, string | boolean>;
const num: OnlyNumbers = 42; // OK
- 解释:在上面的例子中,
Exclude<AllNumbers, string | boolean>从联合类型AllNumbers中排除了string和boolean,只保留了number。
8. Extract<T, U> 类型
Extract<T, U> 从类型 T 中提取出 U 类型中的所有成员,生成一个新的类型。
示例
typescript
CopyEdit
type AllNumbers = number | string | boolean;
type OnlyNumbers = Extract<AllNumbers, number>;
const num: OnlyNumbers = 42; // OK
- 解释:在上面的例子中,
Extract<AllNumbers, number>提取了AllNumbers中的number类型,生成了一个新的类型OnlyNumbers。
9. NonNullable<T> 类型
NonNullable<T> 会从类型 T 中去除 null 和 undefined。
示例
typescript
CopyEdit
type Nullable = string | null | undefined;
type NonNullableString = NonNullable<Nullable>;
const str: NonNullableString = 'Hello'; // OK
// const invalid: NonNullableString = null; // 错误
- 解释:在上面的例子中,
NonNullable<Nullable>会去除null和undefined,返回一个不包含null和undefined的类型。
总结
TypeScript 提供了许多强大的内置类型来帮助你操作类型结构:
Required<T>:将所有属性变为必需。Partial<T>:将所有属性变为可选。Readonly<T>:将所有属性变为只读。Record<K, T>:通过一组键和值类型构建对象类型。Pick<T, K>:从类型T中选择某些属性。Omit<T, K>:从类型T中去除某些属性。Exclude<T, U>:从类型T中排除U中的成员。Extract<T, U>:从类型T中提取U中的成员。NonNullable<T>:去除null和undefined。