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
関数を用いて、エンムの値から文字列リテラル型連合を作成する方法もあります。
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"]
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"
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"]
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 4.4.3 を使用して動作確認しています。
- 上記のサンプルコードは、あくまでも基本的な使い方を示したものであり、すべての状況に適用できるわけではありません。
- 詳細については、TypeScript の公式ドキュメントを参照してください。
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
型エイリアスとジェネリック型を使用して、エンムの型から文字列リテラル型連合を作成しています。
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 の機能を使用している場合は、新しい方法が利用できる可能性があります。
typescript enums