1. 给已有对象添加类型
typescript
const page = {num:number} // 给对象添加size属性且不报错
type Addatr = typeof page & size:number
(page as Addatr).size = 33
const page = {num:number} // 给对象添加size属性且不报错
type Addatr = typeof page & size:number
(page as Addatr).size = 33
2.对象所有属性可选
typescript
type $Partial<T> = {
[Key in keyof T]? = T[Key]
}
type C = $Partial<{a:string,b:number}>
type $Partial<T> = {
[Key in keyof T]? = T[Key]
}
type C = $Partial<{a:string,b:number}>
3.对象所有属性只读
typescript
type $ReadOnly<T> = {
readOnly [Key in keyof T]:T[Key]
}
type readOnlyObj = $ReadOnly<{a:123,b:234}>
//eg:
let obj:readOnlyobj = {
a:123,
b:234
}
type $ReadOnly<T> = {
readOnly [Key in keyof T]:T[Key]
}
type readOnlyObj = $ReadOnly<{a:123,b:234}>
//eg:
let obj:readOnlyobj = {
a:123,
b:234
}
4.对象属性只读且可选
typescript
type ReadonluAndchooese = $ReadOnly<Partial<{ a: string; b: boolean }>>;
type ReadonluAndchooese = $ReadOnly<Partial<{ a: string; b: boolean }>>;
5.infer
typescript
type ParamType<T> = T extends (param: infer P) => any ? P : T;
type ParamType<T> = T extends (param: infer P) => any ? P : T;
在这个条件语句 T extends (param: infer P) => any ? P : T 中,infer P 表示待推断的函数参数。
整句表示为:如果 T 能赋值给 (param: infer P) => any,则结果是 (param: infer P) => any 类型中的参数 P,否则返回为 T。
typescript
interface User {
name: string;
age: number;
}
type Func = (user: User) => void;
type Param = ParamType<Func>; // Param = User
type AA = ParamType<string>; // string
interface User {
name: string;
age: number;
}
type Func = (user: User) => void;
type Param = ParamType<Func>; // Param = User
type AA = ParamType<string>; // string
5.从对象中取一些需要的属性组成联合类型
typescript
type $Pick<T, K extends keyof T> = { [Key in K]: K[T] };
type obj = $Pick<{ a: 123; b: 234; c: 346 }, "a">; // {a:123}
type $Pick<T, K extends keyof T> = { [Key in K]: K[T] };
type obj = $Pick<{ a: 123; b: 234; c: 346 }, "a">; // {a:123}
6.Omit<T,K>从类型 T 中剔除 K 的所有属性
typescript
type MyOmit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type Obj = {
name: "jack";
age: 22;
};
type TestOmit = MyOmit<Obj, "name">; // {name:'jack'} //
type MyOmit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type Obj = {
name: "jack";
age: 22;
};
type TestOmit = MyOmit<Obj, "name">; // {name:'jack'} //
7.Include
typescript
// type isPillarMen = Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Dio'> // expected to be `false`
// 先将数组转化为一个value为true的对象,然后再判断属性是否为有这个为true的属性
type MyIncludes<T, K extends string> = {
[P in T[number]]: true;
}[A] extends true
? true
: false;
// type isPillarMen = Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Dio'> // expected to be `false`
// 先将数组转化为一个value为true的对象,然后再判断属性是否为有这个为true的属性
type MyIncludes<T, K extends string> = {
[P in T[number]]: true;
}[A] extends true
? true
: false;
//注意
T[number] 用来获取数组元素类型的集合(转为数组的联合类型)
T[length] 用来获取数组元素类型集合的长度
8.Concat
typescript
type Concat<T extends readonly any[], U> = U extends any[]
? [...T, ...U]
: [...T, U];
const arr = [1, 2, 3, 4] as const;
type ConcatArr = Concat<typeof arr, 5>; // 1,2,3,4,5
type Concat<T extends readonly any[], U> = U extends any[]
? [...T, ...U]
: [...T, U];
const arr = [1, 2, 3, 4] as const;
type ConcatArr = Concat<typeof arr, 5>; // 1,2,3,4,5
...T 可以枚举数组类型
9.深度 Readonly
typescript
const obj = {
name:'ayu',
age:22,
friends:{
f1:{
name:'tom',
age:33
},
f2:{
name:'jack',
age:44
}
}
type IsObject<T> = keyof T extends never ? false : true
type DeepReadonly<T>={
readonly [ P in keyof T ]:IsObject<T[ p ]> extends true ? DeepReadonly<T[ P ]> : T[ P ]
}
const obj = {
name:'ayu',
age:22,
friends:{
f1:{
name:'tom',
age:33
},
f2:{
name:'jack',
age:44
}
}
type IsObject<T> = keyof T extends never ? false : true
type DeepReadonly<T>={
readonly [ P in keyof T ]:IsObject<T[ p ]> extends true ? DeepReadonly<T[ P ]> : T[ P ]
}
10.元组转联合类型
typescript
type Arr = [1, 2, 3, 4];
type TupleToUnion<T> = T[number];
type Arr = [1, 2, 3, 4];
type TupleToUnion<T> = T[number];
11.获取数组最后一个元素的类型
typescript
// 最后一个元素
type LastEle<T extends any[]> = T extends [...infer A, infer B] ? B : never;
type A1 = [1, 2, 3, 4];
type ReultA = LastEle<A1>;
// 最后一个元素
type LastEle<T extends any[]> = T extends [...infer A, infer B] ? B : never;
type A1 = [1, 2, 3, 4];
type ReultA = LastEle<A1>;
12.Pop
实现一个通用 Pop<T> 接受一个数组 T 并返回一个没有最后一个元素的数组
typescript
type Pop<T extends any[]> = T extends [...infer A, infer B] ? A : never;
type Pop<T extends any[]> = T extends [...infer A, infer B] ? A : never;
13.去除字符串空格
typescript
type TWiteSpace = " ";
type TrimLeft<T extends string> = T extends `${TWiteSpace}${infer B}`
? TrimLeft<B>
: T;
type FilterStrStartTrim = TrimLeft<" hello world ">; // 'hello world '
type TWiteSpace = " ";
type TrimLeft<T extends string> = T extends `${TWiteSpace}${infer B}`
? TrimLeft<B>
: T;
type FilterStrStartTrim = TrimLeft<" hello world ">; // 'hello world '
typescript
type TWiteSpace = ' '
type TrimLeft<T extends string> = T extends `${TWiteSpace}${infer B}` ? TrimLeft<B> : S
type TrimRight<T extends string> = T extends `${infer A}${TWiteSpace}` ? TrimRight<A> : S
type FilterStrTrim = <TrimLeft<TrimRight<' hello world '>>>
type TWiteSpace = ' '
type TrimLeft<T extends string> = T extends `${TWiteSpace}${infer B}` ? TrimLeft<B> : S
type TrimRight<T extends string> = T extends `${infer A}${TWiteSpace}` ? TrimRight<A> : S
type FilterStrTrim = <TrimLeft<TrimRight<' hello world '>>>
14.Replace
typescript
// type replaced = Replace<'types are fun!', 'fun', 'awesome'> // expected to be 'types are awesome!'
type Replace<
S extends string,
From extends string,
To extends string
> = From extends ""
? S
: S extends `${infer L}${From}${infer R}`
? `${L}${To}${R}`
: S;
// type replaced = Replace<'types are fun!', 'fun', 'awesome'> // expected to be 'types are awesome!'
type Replace<
S extends string,
From extends string,
To extends string
> = From extends ""
? S
: S extends `${infer L}${From}${infer R}`
? `${L}${To}${R}`
: S;
15.ReplaceAll
typescript
type ReplaceAll<
S extends string,
From extends string,
To extends string
> = From extends ""
? S
: S extends `${infer L}${From}${infer R}`
? `ReplaceAll<L,From,To>${To}${ReplaceAll<R, From, To>}`
: S;
// 分别将左右两边的进行机递归处理
type ReplaceAll<
S extends string,
From extends string,
To extends string
> = From extends ""
? S
: S extends `${infer L}${From}${infer R}`
? `ReplaceAll<L,From,To>${To}${ReplaceAll<R, From, To>}`
: S;
// 分别将左右两边的进行机递归处理
16。分布式条件类型的理解
会把 extends 左边的类型进行循环处理,然后重新组成联合类型
typescript
type D<A, B = A> = A extends A ? { a: A; b: B } : never;
type R = D<"a" | "b" | "c">;
/*
type R = {
a: "a";
b: "a" | "b" | "c";
} | {
a: "b";
b: "a" | "b" | "c";
} | {
a: "c";
b: "a" | "b" | "c";
}
*/
type D<A, B = A> = A extends A ? { a: A; b: B } : never;
type R = D<"a" | "b" | "c">;
/*
type R = {
a: "a";
b: "a" | "b" | "c";
} | {
a: "b";
b: "a" | "b" | "c";
} | {
a: "c";
b: "a" | "b" | "c";
}
*/
17.判断类型是否为联合类型
typescript
type IsUnion<A, B = A> = A extends A ? ([B] extends [A] ? false : true) : false;
type CC = ISUnion<"a" | "b">; // true
type DD = IsUnion<"a">; // false
type IsUnion<A, B = A> = A extends A ? ([B] extends [A] ? false : true) : false;
type CC = ISUnion<"a" | "b">; // true
type DD = IsUnion<"a">; // false
给类型加数组是为了防止它循环