当您不想重复自己时,有时类型需要基于另一种类型。
映射类型基于索引签名的语法,用于声明尚未提前声明的属性的类型。
tsTry
typeOnlyBoolsAndHorses = {[key : string]: boolean |Horse ;};constconforms :OnlyBoolsAndHorses = {del : true,rodney : false,};
映射类型是一种泛型类型,它使用 PropertyKey
的并集(通常通过 keyof
创建)来迭代键以创建类型。
tsTry
typeOptionsFlags <Type > = {[Property in keyofType ]: boolean;};
在此示例中,OptionsFlags
将获取类型 Type
中的所有属性,并将它们的值更改为布尔值。
tsTry
typeFeatures = {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
子句重新映射映射类型中的键。
ts
type MappedTypeWithNewProperties<Type> = {[Properties in keyof Type as NewKeyType]: Type[Properties]}
您可以利用 模板字面量类型 等功能从之前的属性名创建新的属性名。
tsTry
typeGetters <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
的联合类型,还可以遍历任何类型的联合类型。
tsTry
typeEventConfig <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
。
tsTry
typeExtractPII <Type > = {[Property in keyofType ]:Type [Property ] extends {pii : true } ? true : false;};typeDBFields = {id : {format : "incrementing" };name : {type : string;pii : true };};typeObjectsNeedingGDPRDeletion =ExtractPII <DBFields >;