[解決済み] Typescript はタプル/配列の値からユニオン型を導出します。
質問
リストがあるとします
const list = ['a', 'b', 'c']
この値から、次のようなユニオン型を導出することは可能でしょうか?
'a' | 'b' | 'c'
?
私は、静的配列からの値のみを許可する型を定義したいので、これが必要です。また、実行時にこれらの値を列挙する必要があるので、私は配列を使用します。
インデックス付きオブジェクトでの実装例です。
const indexed = {a: null, b: null, c: null}
const list = Object.keys(index)
type NeededUnionType = keyof typeof indexed
インデックス付きマップを使わずにできないかな。
どのように解決するのですか?
UPDATE 2019年2月
で
2019年3月にリリースされる予定のTypeScript 3.4
のタプルの型を推論するようにコンパイラに指示することができるようになります。
リテラルのタプルとして
のようにではなく、例えば
string[]
を使用することで
as const
構文
. このタイプのアサーションは、コンパイラが値に対して可能な限り狭い型を推論するようにし、すべての
readonly
. このように表示されるはずです。
const list = ['a', 'b', 'c'] as const; // TS3.4 syntax
type NeededUnionType = typeof list[number]; // 'a'|'b'|'c';
これにより、いかなる種類のヘルパー関数も不要になります。 皆さん、また頑張ってください。
UPDATE 2018年7月号
どうやら、TypeScript 3.0から、TypeScriptで
自動的にタプルの型を推論する
. リリースされると
tuple()
の関数は、簡潔に次のように書くことができます。
export type Lit = string | number | boolean | undefined | null | void | {};
export const tuple = <T extends Lit[]>(...args: T) => args;
そして、このように使うことができます。
const list = tuple('a','b','c'); // type is ['a','b','c']
type NeededUnionType = typeof list[number]; // 'a'|'b'|'c'
これでみんなに使ってもらえるといいんだけどなー。
UPDATE 2017年12月
この回答を投稿してから、ライブラリに関数を追加してくれるなら、タプル型を推論する方法が見つかりました。 関数をチェックアウトする
tuple()
で
tuple.ts
. それを使って、以下のように書くと、繰り返しにならずに済みます。
const list = tuple('a','b','c'); // type is ['a','b','c']
type NeededUnionType = typeof list[number]; // 'a'|'b'|'c'
がんばってください
ORIGINAL 2017年7月号
一つの問題は、リテラル
['a','b','c']
という型として推論されます。
string[]
そのため、型システムは特定の値について忘れてしまいます。 各値をリテラル文字列として記憶するよう、型システムに強制することができます。
const list = ['a' as 'a','b' as 'b','c' as 'c']; // infers as ('a'|'b'|'c')[]
あるいは、リストをタプル型として解釈する方がいいかもしれません。
const list: ['a','b','c'] = ['a','b','c']; // tuple
これは迷惑な繰り返しですが、少なくとも実行時に余計なオブジェクトを導入することはありません。
これで、こんな感じでユニオンを取得できます。
type NeededUnionType = typeof list[number]; // 'a'|'b'|'c'.
お役に立てれば幸いです。
関連
-
[解決済み】tsconfigファイルにおけるesModuleInteropの理解
-
[解決済み】Typescript: スプレッド型はオブジェクト型からしか作成できない
-
[解決済み] 型{ [key: string]: boolean; }は何を意味するのでしょうか?
-
ts 学習日記1 AssertionError [ERR_ASSERTION]: タスク関数を指定する必要があります
-
[解決済み] TypeScriptで、「extends keyof」と「in keyof」はどういう意味ですか?
-
[解決済み] モジュール 'module-name' の宣言ファイルが見つかりませんでした。'/path/to/module-name.js' は暗黙のうちに 'any' 型を持っています。
-
[解決済み] TypeScriptで配列の項目を削除するには?
-
[解決済み] TypeScriptのオブジェクトリテラルでの型定義
-
[解決済み] Typescript によるインターフェース型チェック
-
[解決済み】ブロックに`@ts-ignore`を使用するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] タイプスクリプトのエラーです。TS7053 要素が暗黙のうちに 'any' 型を持っています。
-
[解決済み] 型{ [key: string]: boolean; }は何を意味するのでしょうか?
-
[解決済み] Jest で typescript を使用して identity-obj-proxy を使用すると未定義が返される
-
[解決済み] グローバル定数の定義
-
[解決済み] TypeScriptでグローバル変数を作成する
-
[解決済み] フォーインステートメント
-
[解決済み] TypeScriptのInterface Function Property。何が違うの?
-
[解決済み] TypeScriptでオブジェクトを初期化する方法
-
[解決済み】Visual Studio Codeで.js.mapファイルを非表示にする方法
-
[解決済み】Typescriptのパラメータ名のクエスチョンマークとは?