DRY原则(Don'trepeatyourself)是软件开发中最重要的原则之一,即不要重复自己。应避免代码中两个或多个地方的业务逻辑重复。在TypeScript中,映射类型可以帮助我们避免编写重复的代码,它可以根据现有类型和定义的规则创建新的类型。让我们来看看什么是映射类型以及如何构建自己的映射类型。1.基本概念在介绍映射类型之前,我们先来看一些前置知识。(1)IndexedAccessType在TypeScript中,我们可以通过名称查找来访问属性的类型:typeAppConfig={username:string;布局:字符串;};输入用户名=AppConfig["用户名"];本例中,通过AppConfigtype的索引用户名获取其类型字符串,类似于JavaScript中通过索引获取对象的属性值。(2)索引签名当类型属性的实际名称未知但它们将引用的数据类型已知时,索引签名很方便。输入User={名称:字符串;首选项:{[键:字符串]:字符串;}};constcurrentUser:User={name:'FooBar',preferences:{lang:'en',},};constcurrentLang=currentUser.preferences.lang;在上面的例子中,currentLang的类型是string而不是any。此功能与keyof运算符配合使用,是使映射类型成为可能的核心要素之一。(3)接头类型接头类型是两种或多种类型的组合。它表示值的类型可以是联合中包含的任何一种类型。类型StringOrNumberUnion=字符串|数字;让值:StringOrNumberUnion='你好,世界!';值=100;这是一个更复杂的示例,其中编译器可以为联合类型提供一些高级保护:typeAnimal={name:string;物种:字符串;};类型Person={名称:字符串;年龄:数字;};类型AnimalOrPerson=Animal|人;常量值:AnimalOrPerson=loadFromSomewhereElse();console.log(value.name);//?控制台。日志(价值。年龄);//?if('age'invalue){console.log(value.age);//?}在这个例子中,因为Animal和Person都有name属性,所以第15行的value.name可以正常输出,没有报错。而第16行的value.age会被编译错误,因为如果value是Animal类型,那么该value就没有age属性。在第19行的if块中,只能输入此代码块,因为该值具有age属性。所以在这个if块中,value一定是Person,TS可以知道这个value一定有age属性,所以编译是正确的。(4)keyof类型运算符keyof类型运算符返回传递给它的类型的键的联合。输入AppConfig={用户名:字符串;布局:字符串;};输入AppConfigKey=keyofAppConfig;在此示例中,AppConfigKey类型将被解析为“用户名”|“布局”。它可以与索引签名一起使用:typeUser={name:string;首选项:{[键:字符串]:字符串;}};输入UserPreferenceKey=keyofUser["preferences"];在这里,UserPreferenceKeytype被解析为字符串|数字。(5)元组类型元组是一种特殊类型的数组,其中数组的元素在特定索引处可能是特定类型。它们允许TypeScript编译器围绕值数组提供更多安全性,尤其是当这些值属于不同类型时。例如,TypeScript编译器能够为元组的各种元素提供类型安全:typeCurrency=[number,string];常量:货币=[100,''];functionadd(values:number[]){returnvalues.reduce((a,b)=>a+b);}add(amount);//错误:“货币”类型的参数不可分配给类型的参数'number[]'.//类型'string'不可分配给类型'number'。上面的代码会报错。不能将Currency类型的参数赋值给“number[]”类型的参数,也不能将字符串类型赋值给number类型。当访问超出元组定义类型的索引处的元素时,TypeScript可以提示:typeLatLong=[number,number];constloc:LatLong=[48.858370,2.294481];console.log(loc[2]);//错误:长度为“2”的元组类型“LatLong”在索引“2”处没有元素。在这里,元组类型LatLong只有两个元素。当试图访问第三个元素时,会报错。(6)条件类型条件类型是一个表达式,类似于JavaScript中的三元表达式。它的语法如下:TextendsU?X:Y让我们看一个实际的例子:typeConditionalType=stringextendsboolean?字符串:布尔值;在上面的示例中,ConditionalType的类型将为boolean,因为条件字符串extendsboolean始终为false。2.映射类型(1)初体验在TypeScript中,当您需要从另一种类型派生(并保持同步)另一种类型时,使用映射类型特别有用。//用户的配置值typeAppConfig={username:string;布局:字符串;};//用户是否有权限更改配置值typeAppPermissions={changeUsername:boolean;改变布局:布尔值;};上述代码中,AppConfig与AppPermissions之间存在隐式关系,每当AppConfig添加新的配置值时,A??ppPermissions中也必须有对应的布尔值。这里可以使用映射类型来管理两者的关系:typeAppConfig={username:string;布局:字符串;};typeAppPermissions={[AppConfigkeyof中的Propertyas`change${Capitalize
