當你不想重複自己時,有時需要基於另一個型別來定義一個型別。
對映型別基於索引簽名的語法,索引簽名用於宣告未預先宣告的屬性型別。
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 >
進一步探索
對映型別與本型別操作章節中的其他特性結合得很好,例如,這裡有一個使用了條件型別的對映型別,它根據物件是否將 pii 屬性設定為字面量 true,返回 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 >;