マップ型

自分自身を繰り返したくない場合は、型を別の型に基づかせる必要があります。

マップ型はインデックスシグネチャの構文に基づいて構築されます。インデックスシグネチャは、事前に宣言されていないプロパティの型を宣言するために使用されます。

ts
type OnlyBoolsAndHorses = {
[key: string]: boolean | Horse;
};
 
const conforms: OnlyBoolsAndHorses = {
del: true,
rodney: false,
};
Try

マップ型は、`PropertyKey`のユニオン(多くの場合、`keyof`を介して作成されます)を使用してキーを反復処理し、型を作成するジェネリック型です。

ts
type OptionsFlags<Type> = {
[Property in keyof Type]: boolean;
};
Try

この例では、`OptionsFlags`は型`Type`からすべてのプロパティを取得し、それらの値をブール値に変更します。

ts
type Features = {
darkMode: () => void;
newUserProfile: () => void;
};
 
type FeatureOptions = OptionsFlags<Features>;
type FeatureOptions = { darkMode: boolean; newUserProfile: boolean; }
Try

マッピング修飾子

マッピング中に適用できる2つの追加の修飾子があります。`readonly`と`?`は、それぞれ変更可能性とオプション性に影響します。

`-`または`+`を前に付けることで、これらの修飾子を削除または追加できます。接頭辞を追加しない場合、`+`が想定されます。

ts
// Removes 'readonly' attributes from a type's properties
type CreateMutable<Type> = {
-readonly [Property in keyof Type]: Type[Property];
};
 
type LockedAccount = {
readonly id: string;
readonly name: string;
};
 
type UnlockedAccount = CreateMutable<LockedAccount>;
type UnlockedAccount = { id: string; name: string; }
Try
ts
// Removes 'optional' attributes from a type's properties
type Concrete<Type> = {
[Property in keyof Type]-?: Type[Property];
};
 
type MaybeUser = {
id: string;
name?: string;
age?: number;
};
 
type User = Concrete<MaybeUser>;
type User = { id: string; name: string; age: number; }
Try

`as`によるキー再マッピング

TypeScript 4.1以降では、マップ型で`as`句を使用してキーを再マップできます。

ts
type MappedTypeWithNewProperties<Type> = {
[Properties in keyof Type as NewKeyType]: Type[Properties]
}

テンプレートリテラル型などの機能を活用して、以前のプロパティ名から新しいプロパティ名を作成できます。

ts
type Getters<Type> = {
[Property in keyof Type as `get${Capitalize<string & Property>}`]: () => Type[Property]
};
 
interface Person {
name: string;
age: number;
location: string;
}
 
type LazyPerson = Getters<Person>;
type LazyPerson = { getName: () => string; getAge: () => number; getLocation: () => string; }
Try

条件付き型を介して`never`を生成することにより、キーを除外できます。

ts
// Remove the 'kind' property
type RemoveKindField<Type> = {
[Property in keyof Type as Exclude<Property, "kind">]: Type[Property]
};
 
interface Circle {
kind: "circle";
radius: number;
}
 
type KindlessCircle = RemoveKindField<Circle>;
type KindlessCircle = { radius: number; }
Try

`string | number | symbol`のユニオンだけでなく、任意の型のユニオンをマップできます。

ts
type EventConfig<Events extends { kind: string }> = {
[E in Events as E["kind"]]: (event: E) => void;
}
 
type SquareEvent = { kind: "square", x: number, y: number };
type CircleEvent = { kind: "circle", radius: number };
 
type Config = EventConfig<SquareEvent | CircleEvent>
type Config = { square: (event: SquareEvent) => void; circle: (event: CircleEvent) => void; }
Try

詳細

マップ型はこの型の操作セクションの他の機能とうまく連携します。たとえば、条件付き型を使用したマップ型は、オブジェクトにプロパティ`pii`がリテラル`true`に設定されているかどうかによって、`true`または`false`を返します。

ts
type ExtractPII<Type> = {
[Property in keyof Type]: Type[Property] extends { pii: true } ? true : false;
};
 
type DBFields = {
id: { format: "incrementing" };
name: { type: string; pii: true };
};
 
type ObjectsNeedingGDPRDeletion = ExtractPII<DBFields>;
type ObjectsNeedingGDPRDeletion = { id: false; name: true; }
Try

TypeScriptのドキュメントはオープンソースプロジェクトです。プルリクエストを送信して、これらのページの改善にご協力ください❤

このページの貢献者
OTOrta Therox (7)
SFSergey Falinsky (2)
LLuke (1)
Wwebstrand (1)
SGHSteven G. Harms (1)
5+

最終更新日: 2024年3月21日