Typescriptで文字列リテラルtypeを比較に用いたい
code: literal.ts
type Direction = "North" | "South" | "East" | "West";
const currentDirection: DirectionOrString = "West";
みたいなものを用意した時、DirectionからWest, North, South, Eastを抜き出して比較で使いたいときがある。
しかし、それはできない。typeはjavascriptにコンパイルされると消えるため、ここに打ち込まれた文字列はjacascript
では参照できない。
左: typescript 右: javascript なんも出てきてない。
https://gyazo.com/92630e711fbbb6322e5791fd1827a29f
しかし、どうにかして使いたい。
typeであり得る要素でfor文使いたいとかなったら配列からtypeを作るようにすればいい。
配列からtypeを生成する
code:literal2.ts
const tuple = <T extends string[]>(...args: T) => args; // タプル
const directions = tuple("East", "West", "North", "South"); // 方角の配列
type Direction = typeof directionsnumber; // 方角の配列からtypeを生成 type DirectionOrString = Direction | string;
const currentDirection: DirectionOrString = "East";
if (directions.some(x => x === currentDirection)) {}
こうやってかけば directionsからtypeになってる文字列を抜き出せる。
typescript 3.4以降
code:literal3.ts
type Direction = typeof directionsnumber; ユーザータイプガード
code: literal4.ts
type Direction = typeof directionsnumber; const isDirection = (arg: any): arg is Direction => directions.some(direction => direction === arg);
const someFunction = (str: string) => {
if (isDirection(str)) {
const dir: Direction = str; // タイプガードでdirection型
}
}
Enumを利用する
code:.ts
const enum directions {
"East" = "East",
"West" = "West",
"North" = "North",
"South" = "South"
};
type Direction = keyof typeof directions; // "East" | "West" | "North" | "South"
const someFunction = (str: Direction) => {}