当前位置: 首页 > 科技观察

有了TS映射类型,同行直呼专家!

时间:2023-03-19 01:27:26 科技观察

Partial、Required、Pick、Readonly工具类型你用过吗?你知道他们内部是如何运作的吗?如果你想彻底掌握它们并实现自己的工具类型,那么本文介绍的内容一定不能错过。在日常工作中,用户注册是一个很常见的场景。这里我们可以使用TS来定义一个User类型,其中所有的键都是必需的。输入User={名称:字符串;//名称密码:字符串;//密码地址:字符串;//地址电话:字符串;//联系电话};通常,对于注册用户,我们只允许用户修改部分用户信息。此时,我们可以定义一个新的UserPartial类型,它表示用于更新的用户对象的类型,该类型中的所有键都是可选的。输入UserPartial={名称?:字符串;//名称密码?:string;//密码地址?:string;//地址电话?:字符串;//联系电话};用户对象对应的对象类型中的所有键都是只读的。针对这个需求,我们可以定义ReadonlyUser类型。输入ReadonlyUser={只读名称:字符串;//名称只读密码:字符串;//密码只读地址:字符串;//地址只读phone:string;//联系电话};类型,你会发现它们包含很多重复的代码。那么如何减少上述类型中的重复代码呢?答案是使用映射类型,它是一种通用类型,可用于将原始对象类型映射到新的对象类型。映射类型的语法如下:{[PinK]:T}其中PinK类似于JavaScript中的for...in语句,用于遍历K类型中的所有类型,而T类型变量用于表示任何类型的。您还可以使用两个附加修饰符readonly和?在映射过程中。通过在它们前面加上+和-来添加和删除相应的修饰符。如果不加前缀,默认使用+。现在我们可以总结一下常见的映射类型语法:{[PinK]:T}{[PinK]?:T}{[PinK]-?:T}{readonly[PinK]:T}{readonly[PinK]?:T}{-readonly[PinK]?:T}介绍完映射类型的语法,我们来看一些具体的例子:typeItem={a:string;b:数量;c:boolean};typeT1={[Pin"x"|“y”]:数字};//{x:number,y:number}typeT2={[“x”中的P|“y”]:P};//{x:"x",y:"y"}typeT3={[Pin"a"|"b"]:项目[P]};//{a:string,b:number}typeT4={[PinkeyofItem]:Item[P]};//{a:string,b:number,c:boolean}让我们看看如何使用映射类型重新定义UserPartial类型:typeMyPartial={[PinkeyofT]?:T[P];};键入UserPartial=MyPartial;在上面的代码中,我们定义了MyPartial映射类型,然后使用这个类型将User类型Mapped转换为UserPartial类型。其中,keyof运算符用于获取某个类型的所有键,其返回类型为联合类型。类型变量P将在每次遍历时更改为不同的类型。T[P]的语法类似于属性访问的语法,用于获取对象类型的某个属性对应的值的类型。TypeScript4.1版允许我们使用as子句重新映射映射类型中的键。它的语法如下:typeMappedTypeWithNewKeys={[KinkeyofTasNewKeyType]:T[K]//^^^^^^^^^^^^^//这是新语法!}其中NewKeyType的类型必须是字符串|的子类型编号|符号联合类型。使用as子句,我们可以定义一个Getters工具类型,为对象类型生成对应的Getter类型:typeGetters={[KinkeyofTasget${Capitalize}`]:()=>T[K]};interfacePerson{name:string;年龄:数字;location:string;}typeLazyPerson=Getters;//{//getName:()=>string;//getAge:()=>number;//getLocation:()=>string;//}上面代码中,由于keyofT返回的类型可能包含symbol类型,需要Capitalize工具type需要的类型是string类型的子类型,所以需要通过交集运算符进行类型过滤。此外,在键重新映射期间,我们可以通过返回never类型来过滤键://删除'kind'propertytypeRemoveKindField={[KinkeyofTasExclude]:T[K]};interfaceCircle{kind:"circle";radius:number;}typeKindlessCircle=RemoveKindField;//typeKindlessCircle={//radius:number;//};看完这篇文章,相信你已经了解了映射类型的作用,也知道了TS中的一些工具类型是如何实现的。您喜欢以这种形式学习TS吗?