特殊类型要记清
IsAny
any类型与任何类型的交叉类型都是any,也就是1&any结果是any。
type IsAny<T> = undefined extends (string & T) ? true : false;
type is= IsAny<any>;
其中的string
与undefined
可以换成别的任意两个不同的类型。
IsEqual
判断两个类型是否相同
type IsEqual<A,B> = (A extends B ? true : false) & (B extends A ? true : false);
type is = IsEqual<string,any>;
IsUnion
判断是否是联合类型
type IsUnion<A, B = A> = A extends A ?
[B] extends [A] ?
false :
true
: never;
type is = IsUnion<'1' | 1>;
IsNever
判断是否是never类型。如果条件左边是类型参数,并且传入的是never,那么直接返回never。
type IsNever<T> = T extends number ? 1 : 2;
type is = IsNever<1>;
上面的代码如果判断any会返回1和2的联合类型
type IsNever<T> = T extends number ? 1 : 2;
type is = IsNever<any>;
也可以这样写
type IsNever<T> = [T] extends [never] ? true : false;
type is = IsNever<never>;
IsTuple
判断是不是元组元组是数组类型,但是每个元素都是只读的,并且length是数字字面量,而数组的length是number。
type IsTuple<T> = T extends readonly[...args: infer Eles] ?
NotEqual<Eles['length'],number>
: false;
type NotEqual<A,B> = (<T>()=>T extends A ? 1 : 2) extends (<T>()=>T extends B ? 1 : 2) ? false : true;
type is = IsTuple<number[]>;
联合类型转换成交叉类型
type UnionToIntersection<U> = (U extends U ? (x:U)=>unknown:never) extends (x:infer R)=>unknown ? R : never;
type un = UnionToIntersection<{guang: 1} | {dong: 2}>;
提取索引类型中的可选索引
type GetOptional<Obj extends Record<string,any>> = {
[Key in keyof Obj as {} extends Pick<Obj, Key> ? Key : never]: Obj[Key]
}
type optional = GetOptional<{
name?: 1
age: 2
}>;
提取索引类型中的不可选索引
type isRequired<Obj extends Record<string,any>> = {
[Key in keyof Obj as {} extends Pick<Obj, Key> ? never : Key]: Obj[Key]
}
type optional = isRequired<{
name?: 1
age: 2
}>;
去除索引类型中的索引签名
type Test = {
[Key: string]: any
}
上面就是索引类型中的索引签名索引类型不能构造成字符串字面量类型,因为它没有名字,而其他索引可以。
type RemoveIndexSignature<Obj extends Record<string,any>> = {
[Key in keyof Obj as Key extends `${infer Str}` ? Str : never]: Obj[Key];
}
type index = RemoveIndexSignature<{
name: '1',
[Key: string]: any
}>;
过滤除class的public属性
keyof只能拿到class的public属性,private和protected的索引会被忽略。
type ClassPublicProps<Obj extends Record<string,any>> = {
[Key in keyof Obj]: Obj[Key];
}
class Dong {
public name: string;
protected age: number;
private hobbies: string[];
constructor() {
this.name = 'dong';
this.age = 20;
this.hobbies = ['sleep', 'eat'];
}
}
type public = ClassPublicProps<Dong>;
as const
用const定义的类型,typescript默认推导出来的类型不是字面量类型。例如:
const obj = {
name: 1
}
type objType = typeof obj;
我们可以使用as const来处理。
const obj = {
name: 1
} as const;
type objType = typeof obj;