封装几个常用的 TypeScript 类型体操,并给出简单的例子供参考:
- 限制值域的类型
type ValueOf<T extends ReadonlyArray<unknown>> = T[number];
使用:
type Colors = ReadonlyArray<'red' | 'green' | 'blue'>;
type Color = ValueOf<Colors>; // 'red' | 'green' | 'blue'
- 限制对象的属性值类型
type PropertyOfType<T, U> = {
[K in keyof T]: T[K] extends U ? K : never;
}[keyof T];
使用:
interface Person {
name: string;
age: number;
location: string;
}
type StringKeys = PropertyOfType<Person, string>; // 'name' | 'location'
- 求取对象中某一属性的类型
type ValueOfKey<T, K extends keyof T> = T[K];
使用:
interface Person {
name: string;
age: number;
location: string;
}
type Name = ValueOfKey<Person, 'name'>; // string
- 限制参数类型
type FirstParameter<T> = T extends (arg1: infer P, ...args: any[]) => any ? P : never;
使用:
function greet(name: string, age: number): void {
console.log(`Hello, ${name}! You are ${age} years old.`);
}
type Name = FirstParameter<typeof greet>; // string
这里 Name
类型为 string
,因为 greet
函数的第一个参数类型为 string
。
- 合并两个类型
type Merge<T, U> = Omit<T, keyof U> & U;
使用:
interface Person {
name: string;
age: number;
}
interface Employee {
name: string;
salary: number;
}
type EmployeeRecord = Merge<Person, Employee>; // { name: string; age: number; salary: number; }
- 获取函数返回值类型
type ReturnType<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R : any;
使用:
function add(x: number, y: number): number {
return x + y;
}
type Result = ReturnType<typeof add>; // number
- 将联合类型转换为交叉类型
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
使用:
interface Person {
name: string;
age: number;
}
interface Employee {
salary: number;
position: string;
}
type EmployeePerson = Person & Employee;
type EmployeePersonUnion = Person | Employee;
type EmployeePersonIntersection = UnionToIntersection<EmployeePersonUnion>; // Person & Employee
这里 EmployeePersonUnion
是 Person
和 Employee
的联合类型,而 EmployeePersonIntersection
是 Person
和 Employee
的交叉类型。
- 判断两个类型是否相等
type Equals<T, U> = T extends U ? (U extends T ? true : false) : false;
使用:
type Result1 = Equals<42, 42>; // true
type Result2 = Equals<{ a: number }, { a: number }>; // true
type Result3 = Equals<{ a: number }, { b: number }>; // false
- 排除类型中的某些属性
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
使用:
interface Person {
name: string;
age: number;
location: string;
}
type PersonWithoutLocation = Omit<Person, 'location'>; // { name: string; age: number; }
- 从类型中排除 null 和 undefined
type NonNullable<T> = T extends null | undefined ? never : T;
使用:
type Foo = string | null | undefined | number;
type Bar = NonNullable<Foo>; // string | number
以上是一些常用的 TypeScript 类型体操,希望能对您有所帮助。