TypeScript エンム: `Object.values` 関数を用いて文字列リテラル型連合を作成
TypeScript エンムから文字列リテラル型連合を作成する方法
keyof 演算子を用いる方法
最も一般的な方法は、keyof
演算子を用いて、エンムのキー(定数名)から文字列リテラル型連合を作成する方法です。
enum Direction {
North,
South,
East,
West
}
type DirectionString = keyof Direction; // "North" | "South" | "East" | "West"
この例では、Direction
エンムのキーを DirectionString
という型の文字列リテラル型連合として定義しています。DirectionString
型の変数には、Direction
エンムの値である "North"
, "South"
, "East"
, "West"
のいずれかを代入することができます。
Object.values 関数を用いる方法
Object.values
関数を用いて、エンムの値から文字列リテラル型連合を作成する方法もあります。
enum Direction {
North,
South,
East,
West
}
type DirectionString = typeof Direction[keyof Direction]; // "North" | "South" | "East" | "West"
const directionStrings: DirectionString[] = Object.values(Direction); // ["North", "South", "East", "West"]
この例では、Object.values
関数を用いて、Direction
エンムの値をすべて取得し、directionStrings
という配列に格納しています。directionStrings
配列の要素には、Direction
エンムの値である "North"
, "South"
, "East"
, "West"
のいずれかを代入することができます。
const アサーションを用いる方法
TypeScript 3.4 以降では、const
アサーションを用いて、エンムの値から文字列リテラル型連合を作成する方法もあります。
enum Direction {
North,
South,
East,
West
}
const directionStrings: "North" | "South" | "East" | "West" = Direction; // "North" | "South" | "East" | "West"
TypeScript において、エンムから文字列リテラル型連合を作成する方法には、keyof
演算子を用いる方法、Object.values
関数を用いる方法、const
アサーションを用いる方法の 3 種類があります。それぞれの方法にはメリットとデメリットがあるので、状況に応じて適宜選択しましょう。
メリット
- 型安全性が高い
- エンムの値を文字列として直接使用できる
- コードが冗長になる
- エンムの値を変更するたびに、文字列リテラル型連合を変更する必要がある
enum Direction {
North,
South,
East,
West
}
type DirectionString = keyof Direction; // "North" | "South" | "East" | "West"
function getDirectionString(direction: Direction): DirectionString {
switch (direction) {
case Direction.North:
return "North";
case Direction.South:
return "South";
case Direction.East:
return "East";
case Direction.West:
return "West";
default:
throw new Error("Invalid direction");
}
}
const northString: DirectionString = getDirectionString(Direction.North); // "North"
const southString: DirectionString = getDirectionString(Direction.South); // "South"
const eastString: DirectionString = getDirectionString(Direction.East); // "East"
const westString: DirectionString = getDirectionString(Direction.West); // "West"
enum Direction {
North,
South,
East,
West
}
type DirectionString = typeof Direction[keyof Direction]; // "North" | "South" | "East" | "West"
const directionStrings: DirectionString[] = Object.values(Direction); // ["North", "South", "East", "West"]
function isDirectionString(s: string): s is DirectionString {
return directionStrings.includes(s);
}
const northString: DirectionString = "North"; // "North"
const southString: DirectionString = "South"; // "South"
const eastString: DirectionString = "East"; // "East"
const westString: DirectionString = "West"; // "West"
const invalidString: string = "Invalid"; // string
if (isDirectionString(invalidString)) {
console.log("有効な方向文字列です:", invalidString);
} else {
console.log("無効な方向文字列です:", invalidString);
}
enum Direction {
North,
South,
East,
West
}
const directionStrings: "North" | "South" | "East" | "West" = Direction; // "North" | "South" | "East" | "West"
function isDirectionString(s: string): s is DirectionString {
return directionStrings === s;
}
const northString: DirectionString = "North"; // "North"
const southString: DirectionString = "South"; // "South"
const eastString: DirectionString = "East"; // "East"
const westString: DirectionString = "West"; // "West"
const invalidString: string = "Invalid"; // string
if (isDirectionString(invalidString)) {
console.log("有効な方向文字列です:", invalidString);
} else {
console.log("無効な方向文字列です:", invalidString);
}
- 詳細については、TypeScript の公式ドキュメントを参照してください。
enum Direction {
North,
South,
East,
West
}
type DirectionString = typeof Direction[keyof Direction]; // "North" | "South" | "East" | "West"
function isDirectionString(s: string): s is DirectionString {
return Object.values(Direction).includes(s as Direction);
}
function getDirectionString(direction: Direction): DirectionString | undefined {
if (isDirectionString(direction)) {
return direction;
} else {
return undefined;
}
}
const northString: DirectionString | undefined = getDirectionString(Direction.North); // "North"
const southString: DirectionString | undefined = getDirectionString(Direction.South); // "South"
const eastString: DirectionString | undefined = getDirectionString(Direction.East); // "East"
const westString: DirectionString | undefined = getDirectionString(Direction.West); // "West"
const invalidString: DirectionString | undefined = getDirectionString("Invalid"); // undefined
この例では、isDirectionString
関数と getDirectionString
関数を使用して、エンムの値が文字列リテラル型連合に属しているかどうかを判断しています。
型エイリアスとジェネリック型を用いる方法
enum Direction {
North,
South,
East,
West
}
type DirectionString<T extends Direction> = keyof T;
const directionStrings: DirectionString<Direction> = Direction; // "North" | "South" | "East" | "West"
この例では、DirectionString
型エイリアスとジェネリック型を使用して、エンムの型から文字列リテラル型連合を作成しています。
in 演算子を用いる方法
enum Direction {
North,
South,
East,
West
}
type DirectionString = typeof Direction[keyof Direction]; // "North" | "South" | "East" | "West"
function isDirectionString(s: string): s is DirectionString {
return s in Direction;
}
const northString: DirectionString | undefined = (Direction.North as DirectionString); // "North"
const southString: DirectionString | undefined = (Direction.South as DirectionString); // "South"
const eastString: DirectionString | undefined = (Direction.East as DirectionString); // "East"
const westString: DirectionString | undefined = (Direction.West as DirectionString); // "West"
const invalidString: DirectionString | undefined = ("Invalid" as DirectionString); // undefined
この例では、in
演算子を使用して、エンムの値がエンムオブジェクトに含まれているかどうかを判断しています。
TypeScript エンムから文字列リテラル型連合を作成するには、様々な方法があります。それぞれの方法にはメリットとデメリットがあるので、状況に応じて適宜選択しましょう。
- すべての状況に適用できるわけではない
- 理解が難しい
注意事項
- 最新の TypeScript の機能を使用している場合は、新しい方法が利用できる可能性があります。
typescript enums