这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
因为Typescript的持续火爆,分享下TS的常用知识点,我们一起学习交流,一起加油!
条件类型
- 条件类型在Typescript中应用非常广泛,因为他可以自定义出很多的类型推导,很多TS内置的方法都应用了条件类型,下面会一一讲解,
2.条件类型中主要使用的是extends 和 infer
1. extends 的基本使用
1.单一类型
单一类型就是只有单一的类型,有且只有一个类型
2.分布式
拥有几个类型,利用|来分隔
// 单一类型
interface Fish {
name: string;
}
interface Bird {
name1: string;
}
interface Water {
name3: string;
}
interface Sky {
name4: string;
}
// 如果是Fish的类型就使用water的类型,反之则使用Sky的类型
type C<T> = T extends Fish ? Water : Sky;
let c1: C<Fish> = { name3: "tom" };
let c2: C<Bird> = { name4: "tom" };
//条件类型的分发
interface Shark extends Fish {
swing: string;
}
interface Sprint extends Water {
hot: boolean;
}
// 这个会被解析成 C<Shark> | C<Fish>
let c3: C<Shark | Fish> = { name3: "tom" };
let c4: C<Sprint | Water> = { name4: "tom" };
复制代码
2.条件类型的应用
// 找出T中不包括U的部分,利用的是never 和任何类型 | 都是never
type DiffType<T, U> = T extends U ? never : T;
// Diff可以为boolean 也可以为number
let diff1: DiffType<string | boolean | number, string> = true; //boolean
let diff2: DiffType<string | boolean | number, string> = 1; //number
复制代码
3.一些常用的内置类型对extends的使用
// 提取出T中存在U的部分
type Extract<T, U> = T extends U ? T : never;
let extrac: Extract<string | boolean | number, string> = "string";
// 排除null和undefined类型
type NonNullable<T> = T extends null | undefined ? never : T;
let nonNullable1: NonNullable<string | boolean | null> = "string";
let nonNullable2: NonNullable<string | boolean | null> = true;
// 把所有的属性变成可选的
type Partial<T>= {
[key in keyof T]? : T[key]
}
let partial1:Partial<{a:string,b:boolean}>={a:'1'}
let partial2:Partial<{a:string,b:boolean}>={b:false}
let partial3:Partial<{a:string,b:boolean}>={}
// 把所有的都变成必须的
type Required<T>= {
[key in keyof T]-? : T[key]
}
let required1:Required<{a?:string,b?:boolean}>={a:'1',b:false}
// let rartial2:Required<{a?:string,b?:boolean}>={b:false} // 报错
// let rartial3:Required<{a?:string,b?:boolean}>={}//报错
// 挑选出k中属于T的属性
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
let pickType:Pick<{a:string,b:boolean},'a'>={a:'1'}
//Record<K,T> K中所有的属性都是T
type Record<K extends keyof any, T> = {
[P in K]: T;
};
let recordType:Record<'a'|'b'|'c',string>={a:'1',b:'1',c:'1'}
// 元组转联合类型
type ElementOf<T> = T extends Array<infer E> ? E : never;
type TupleType = [string, number];
type ElementOfType = ElementOf<TupleType>;
let elementOfType1: ElementOfType = "s";
let elementOfType2: ElementOfType = 1;
// 深度partial
type DeepPartial<T> = {
[U in keyof T]?: T[U] extends object ? DeepPartial<T[U]> : T[U];
};
type A ={
name:string,
age:number,
person:{
hasFeet:boolean,
hasHair:boolean,
}
}
let deepPartialType1:DeepPartial<A> ={
name:'1',
}
let deepPartialType2:DeepPartial<A> ={
person:{
hasFeet:true
}
}
let deepPartialType3:DeepPartial<A> ={
age:1,
}
复制代码
4.infer 类型的使用
// infer 相当于一个定义变量的符合,只要使用了Infer 就可以取到对应的类型
type Infer<T extends (a:any,b:any)=>any > = T extends (a:string,b:infer P)=>any? P:never
let infer1:Infer<(a:string, b:number)=> string >= 1
复制代码
5.内置工具对infer 的使用
内置工具对infer的使用非常广泛
//返回T 中的return 的类型
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
let returnType:ReturnType<(a:string)=>string>='1'
//返回T 中的参数
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
let a = 1;
let parametersType:Parameters<(a:number)=>string>=[a]
//返回构造函数中的参数
type ConstructorParameters<T extends abstract new (...args: any) => any> = T extends abstract new (...args: infer P) => any ? P : never;
class Person {
constructor(public name:string){}
}
let b = 'Tom';
let constructorParametersType:ConstructorParameters<typeof Person>=[b]
//返回实力对象的类型
type InstanceType<T extends abstract new (...args: any) => any> =T extends abstract new (...args: any) => infer R ? R : any;
let person =new Person('tom')
let instanceTypeType:InstanceType<typeof Person>=person;
复制代码
代理
类型在TS中很重要,代理可以把类型通过代理添加一些功能
1. proxy 加代理
any和任何元素组合的都是any类型
type Proxy<T> = {
get(): T;
set(value: T): void;
};
type Proxify<T> = {
[P in keyof T]: Proxy<T[P]>;
};
function proxify<T>(obj: T): Proxify<T> {
let result: any = <Proxify<T>>{};
for (const key in obj) {
type KeyType = typeof key;
result[key] = {
get: () => {
console.log('get',obj[key]);
return obj[key];
},
set: (value: T[KeyType]) => {
obj[key] = value;
console.log('set',value);
},
};
}
return result;
}
type OBJ = {
name: string;
age: number;
};
const obj: OBJ = {
name: "1",
age: 1,
};
const c: Proxify<OBJ> = proxify<OBJ>(obj);
let name =c1.name // 打印 get 1
c1.name='tom' // 打印 set tom
复制代码
2. unProxify 反代理
利用返代理可以去除掉代理
function unProxify<T>(object: Proxify<T>): T {
const result: any = <T>{};
for (const key in object) {
result[key] = object[key];
}
return result;
}
let c1:OBJ=unProxify<OBJ>(c)
复制代码
相关资料
大家喜欢的可以看看我的专栏 (TypeScript常用知识) 我会尽量保持每天晚上更新,如果喜欢的麻烦帮我点个赞,十分感谢
大家如果喜欢“算法”的话,可以看看我分享的另外一个专栏(前端搞算法)里面有更多关于算法的题目的分享,希望能帮助大家更深的理解算法
文章内容目的在于学习讨论与分享学习算法过程中的心得体会,文中部分素材来源网络,如有侵权,请联系删除,邮箱 182450609@qq.com
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END