主题
特殊特性
IsAny
any 类型与任何类型的交叉都是 any,也就是 1 & any 结果是 any
typescript
type IsAny<T> = 'a' extends ('b' & T) ? true : false
IsEqual
typescript
type IsEqual<A, B> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2)
? true : false
NotEqual
typescript
type NotEqual<A, B> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2)
? false : true
IsUnion
判断 union 类型
typescript
type IsUnion<A, B = A> =
A extends A
? [B] extends [A]
? false
: true
: never
IsNever
typescript
type IsNever<T> = [T] extends [never] ? true : false
IsTuple
元组类型也是数组类型,但每个元素都是只读的,并且 length 是数字字面量,而数组的 length 是 number
typescript
type IsTuple<T> =
T extends readonly [...params: infer Eles]
? NotEqual<Eles['length'], number>
: false
UnionToIntersection
交叉类型转成联合类型
typescript
type UnionToIntersection<U> =
(U extends U ? (x: U) => unknown : never) extends (x: infer R) => unknown
? R
: never
type Result = UnionToIntersection<{ a: 'a' } | { b: 'b' }> // { a: 'a' } & { b: 'b' }
GetOptional
提取索引类型中的可选索引
typescript
type GetOptional<Obj extends Record<string, any>> = {
[
Key in keyof Obj
as {} extends Pick<Obj, Key> ? Key : never
] : Obj[Key];
}
type Result = GetOptional<{
name: string;
age?: number;
}> // { age?: number }
GetRequired
过滤所有非可选的索引构造成新的索引类型
typescript
type isRequired<Key extends keyof Obj, Obj> =
{} extends Pick<Obj, Key> ? never : Key
RemoveIndexSignature
想删除索引类型中的可索引签名
索引签名不能构造成字符串字面量类型,因为它没有名字,而其他索引可以
typescript
type RemoveIndexSignature<Obj extends Record<string, any>> = {
[
Key in keyof Obj
as Key extends `${infer Str}`? Str : never
]: Obj[Key]
}
type Result = RemoveIndexSignature<{ a: number; [key: string]: number }> // { a: number }
ClassPublicProps
过滤出 class 的 public 的属性
keyof 只能拿到 class 的 public 索引,private 和 protected 的索引会被忽略
typescript
type ClassPublicProps<Obj extends Record<string, any>> = {
[Key in keyof Obj]: Obj[Key]
}