内置工具类型(Partial, Required等)
内置工具类型(Partial, Required等)
TypeScript提供了一系列内置工具类型,用于简化类型操作。这些工具类型基于泛型和条件类型,能够帮助开发者更高效地处理类型转换和组合。Partial、Required、Readonly、Pick、Record等是其中最常用的几种。
Partial
Partial工具类型将类型T的所有属性变为可选属性。这在需要部分更新对象时特别有用。
interface User {
id: number;
name: string;
age: number;
}
type PartialUser = Partial<User>;
// 等同于
// {
// id?: number;
// name?: string;
// age?: number;
// }
function updateUser(id: number, changes: Partial<User>) {
// 更新用户逻辑
}
updateUser(1, { name: "张三" }); // 只更新name属性
Partial的实现原理是基于映射类型:
type Partial<T> = {
[P in keyof T]?: T[P];
};
Required
Required与Partial相反,它将类型T的所有属性变为必选属性。
interface Props {
a?: number;
b?: string;
}
type RequiredProps = Required<Props>;
// 等同于
// {
// a: number;
// b: string;
// }
const obj1: Props = { a: 5 }; // 正确
const obj2: RequiredProps = { a: 5 }; // 错误,缺少属性b
Required的实现原理:
type Required<T> = {
[P in keyof T]-?: T[P];
};
Readonly
Readonly工具类型将类型T的所有属性变为只读属性。
interface Todo {
title: string;
}
const todo: Readonly<Todo> = {
title: "学习TypeScript",
};
todo.title = "学习JavaScript"; // 错误,无法分配到"title",因为它是只读属性
Readonly的实现原理:
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
Pick
Pick工具类型从类型T中选择一组属性K来构造新类型。
interface User {
id: number;
name: string;
age: number;
email: string;
}
type UserBasicInfo = Pick<User, "id" | "name">;
// 等同于
// {
// id: number;
// name: string;
// }
const userBasic: UserBasicInfo = {
id: 1,
name: "张三",
};
Pick的实现原理:
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
Record
Record工具类型构造一个类型,其属性键为K,属性值为T。
type PageInfo = {
title: string;
};
type Page = "home" | "about" | "contact";
const nav: Record<Page, PageInfo> = {
home: { title: "首页" },
about: { title: "关于" },
contact: { title: "联系" },
};
Record的实现原理:
type Record<K extends keyof any, T> = {
[P in K]: T;
};
Exclude
Exclude工具类型从类型T中排除那些可以赋值给U的类型。
type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
type T1 = Exclude<string | number | (() => void), Function>; // string | number
Exclude的实现原理:
type Exclude<T, U> = T extends U ? never : T;
Extract
Extract工具类型从类型T中提取那些可以赋值给U的类型。
type T0 = Extract<"a" | "b" | "c", "a" | "f">; // "a"
type T1 = Extract<string | number | (() => void), Function>; // () => void
Extract的实现原理:
type Extract<T, U> = T extends U ? T : never;
Omit
Omit工具类型构造一个类型,它从类型T中删除属性K。
interface User {
id: number;
name: string;
age: number;
email: string;
}
type UserWithoutEmail = Omit<User, "email">;
// 等同于
// {
// id: number;
// name: string;
// age: number;
// }
Omit的实现原理:
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
NonNullable
NonNullable工具类型从类型T中排除null和undefined。
type T0 = NonNullable<string | number | undefined>; // string | number
type T1 = NonNullable<string[] | null | undefined>; // string[]
NonNullable的实现原理:
type NonNullable<T> = T extends null | undefined ? never : T;
Parameters
Parameters工具类型从函数类型T的参数中构造一个元组类型。
declare function f1(arg: { a: number; b: string }): void;
type T0 = Parameters<() => string>; // []
type T1 = Parameters<(s: string) => void>; // [s: string]
type T2 = Parameters<<T>(arg: T) => T>; // [arg: unknown]
type T3 = Parameters<typeof f1>; // [arg: { a: number; b: string }]
Parameters的实现原理:
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
ReturnType
ReturnType工具类型获取函数类型T的返回类型。
declare function f1(): { a: number; b: string };
type T0 = ReturnType<() => string>; // string
type T1 = ReturnType<(s: string) => void>; // void
type T2 = ReturnType<<T>() => T>; // unknown
type T3 = ReturnType<<T extends U, U extends number[]>() => T>; // number[]
type T4 = ReturnType<typeof f1>; // { a: number; b: string }
ReturnType的实现原理:
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
InstanceType
InstanceType工具类型获取构造函数类型的实例类型。
class C {
x = 0;
y = 0;
}
type T0 = InstanceType<typeof C>; // C
type T1 = InstanceType<any>; // any
type T2 = InstanceType<never>; // never
type T3 = InstanceType<string>; // 错误
InstanceType的实现原理:
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;
ThisParameterType
ThisParameterType工具类型提取函数类型的this参数类型。
function toHex(this: Number) {
return this.toString(16);
}
type T0 = ThisParameterType<typeof toHex>; // Number
type T1 = ThisParameterType<(this: Window, name: string) => void>; // Window
type T2 = ThisParameterType<(name: string) => void>; // unknown
ThisParameterType的实现原理:
type ThisParameterType<T> = T extends (this: infer U, ...args: any[]) => any ? U : unknown;
OmitThisParameter
OmitThisParameter工具类型从函数类型中移除this参数。
function toHex(this: Number) {
return this.toString(16);
}
type T0 = OmitThisParameter<typeof toHex>; // () => string
type T1 = OmitThisParameter<(this: Window, name: string) => void>; // (name: string) => void
OmitThisParameter的实现原理:
type OmitThisParameter<T> = unknown extends ThisParameterType<T> ? T : T extends (...args: infer A) => infer R ? (...args: A) => R : T;
ConstructorParameters
ConstructorParameters工具类型从构造函数类型中提取参数类型。
type T0 = ConstructorParameters<ErrorConstructor>; // [message?: string]
type T1 = ConstructorParameters<FunctionConstructor>; // string[]
type T2 = ConstructorParameters<RegExpConstructor>; // [pattern: string | RegExp, flags?: string]
ConstructorParameters的实现原理:
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;
高级组合使用
这些工具类型可以组合使用,创建更复杂的类型操作。
interface User {
id: number;
name: string;
age: number;
email: string;
address?: {
street: string;
city: string;
};
}
// 创建一个只读的、部分更新的用户类型
type ReadonlyPartialUser = Readonly<Partial<User>>;
// 创建一个只包含某些字段且必填的类型
type RequiredUserFields = Required<Pick<User, "id" | "name">>;
// 创建一个排除某些字段的类型
type UserWithoutPrivateInfo = Omit<User, "email" | "address">;
// 创建一个深度Partial类型
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
type DeepPartialUser = DeepPartial<User>;
// 等同于
// {
// id?: number;
// name?: string;
// age?: number;
// email?: string;
// address?: {
// street?: string;
// city?: string;
// };
// }
自定义工具类型
除了内置工具类型,开发者也可以创建自己的工具类型。
// 创建一个Nullable类型
type Nullable<T> = T | null;
// 创建一个Promise返回值类型
type PromiseReturnType<T> = T extends Promise<infer R> ? R : T;
// 创建一个数组元素类型
type ArrayElement<ArrayType extends readonly unknown[]> =
ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
// 创建一个函数参数类型
type FunctionParams<T> = T extends (...args: infer P) => any ? P : never;
// 创建一个合并两个类型的类型
type Merge<A, B> = {
[K in keyof A | keyof B]:
K extends keyof B ? B[K] :
K extends keyof A ? A[K] :
never;
};
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn