当您不想重复自己时,有时类型需要基于另一种类型。
映射类型基于索引签名的语法,用于声明尚未提前声明的属性的类型。
tsTrytypeOnlyBoolsAndHorses = {[key : string]: boolean |Horse ;};constconforms :OnlyBoolsAndHorses = {del : true,rodney : false,};
映射类型是一种泛型类型,它使用 PropertyKey 的并集(通常通过 keyof 创建)来迭代键以创建类型。
tsTrytypeOptionsFlags <Type > = {[Property in keyofType ]: boolean;};
在此示例中,OptionsFlags 将获取类型 Type 中的所有属性,并将它们的值更改为布尔值。
tsTrytypeFeatures = {darkMode : () => void;newUserProfile : () => void;};typeFeatureOptions =OptionsFlags <Features >;
映射修饰符
在映射过程中,可以应用两个额外的修饰符:readonly 和 ?,它们分别影响可变性和可选性。
可以通过在前面添加 - 或 + 来删除或添加这些修饰符。如果不添加前缀,则假定为 +。
tsTry// Removes 'readonly' attributes from a type's propertiestypeCreateMutable <Type > = {-readonly [Property in keyofType ]:Type [Property ];};typeLockedAccount = {readonlyid : string;readonlyname : string;};typeUnlockedAccount =CreateMutable <LockedAccount >;
tsTry// Removes 'optional' attributes from a type's propertiestypeConcrete <Type > = {[Property in keyofType ]-?:Type [Property ];};typeMaybeUser = {id : string;name ?: string;age ?: number;};typeUser =Concrete <MaybeUser >;
通过 as 重映射键
在 TypeScript 4.1 及更高版本中,可以使用映射类型中的 as 子句重新映射映射类型中的键。
tstype MappedTypeWithNewProperties<Type> = {[Properties in keyof Type as NewKeyType]: Type[Properties]}
您可以利用 模板字面量类型 等功能从之前的属性名创建新的属性名。
tsTrytypeGetters <Type > = {[Property in keyofType as `get${Capitalize <string &Property >}`]: () =>Type [Property ]};interfacePerson {name : string;age : number;location : string;}typeLazyPerson =Getters <Person >;
您可以通过生成 never 来过滤掉键,方法是在条件类型中使用条件类型。
tsTry// Remove the 'kind' propertytypeRemoveKindField <Type > = {[Property in keyofType asExclude <Property , "kind">]:Type [Property ]};interfaceCircle {kind : "circle";radius : number;}typeKindlessCircle =RemoveKindField <Circle >;
您可以遍历任意联合类型,不仅是 string | number | symbol 的联合类型,还可以遍历任何类型的联合类型。
tsTrytypeEventConfig <Events extends {kind : string }> = {[E inEvents asE ["kind"]]: (event :E ) => void;}typeSquareEvent = {kind : "square",x : number,y : number };typeCircleEvent = {kind : "circle",radius : number };typeConfig =EventConfig <SquareEvent |CircleEvent >
进一步探索
映射类型与本节中其他类型操作功能配合使用效果很好,例如,这里有一个 使用条件类型的映射类型,它根据对象是否具有设置为文字 true 的属性 pii 返回 true 或 false。
tsTrytypeExtractPII <Type > = {[Property in keyofType ]:Type [Property ] extends {pii : true } ? true : false;};typeDBFields = {id : {format : "incrementing" };name : {type : string;pii : true };};typeObjectsNeedingGDPRDeletion =ExtractPII <DBFields >;