ウェブサイト検索

TypeScript - 文字列リテラル型をリテラル値に変換する


TypeScriptでは、次のようなことを可能にする文字列リテラル型を持つことができます:

type HelloString = "Hello";

これにより、次のように文字列列挙型のようなものを定義できます。

namespace Literals {
    export type One = "one";
    export type Two = "two";
}

そして次に、私はユニオンを定義できます:

type Literal = Literals.One | Literals.Two;

Literals.One のユニークな値を Literals.One 型として抽出する方法はありますか?

これの理由は、私が次のように関数を定義するときです:

function doSomething(literal : Literal) {

}

私は本当に次のことをしたいです:

doSomething(Literals.One);

でも、できません。私は書かなければなりません:

doSomething("one");

回答 #1

名前空間の中で、同じ名前の型と値を持つことができるので、それらの値の定数を定義することができます:

namespace Literals {
    export type One = "one";
    export type Two = "two";
    export const One: One = "one";
    export const Two: Two = "two";
}

const s: Literals.One = Literals.One;
console.log(s);

GitHubには文字列列挙型の提案があり、彼らは現在の最良の解決策は上の例であると示唆しています。

回答 #2

文字列リテラル型をリテラル値に変換することは、カスタムトランスフォーマー(https://github.com/Microsoft/TypeScript/pull/13940)を使用して可能であり、これは typescript@next で利用できます。

私のnpmパッケージ、ts-transformer-enumerateを見てください。

使用例:

// The signature of `enumerate` here is `function enumerate<T extends string>(): { [K in T]: K };`
import { enumerate } from 'ts-transformer-enumerate';

type Colors = 'green' | 'yellow' | 'red';
const Colors = enumerate<Colors>();

console.log(Colors.green); // 'green'
console.log(Colors.yellow); // 'yellow'
console.log(Colors.red); // 'red'

関連記事