TypeScriptでオブジェクトキータイプとしてシンボルを使用する


20

MDNが言うので、キータイプとしてシンボルを使用してオブジェクトを定義しようとしています:

シンボル値は、オブジェクトプロパティの識別子として使用できます[...]

ただし、キープロパティのタイプとして使用します。

type obj = {
    [key: symbol | string]: string
}

次のエラーが発生します。

TS1023:インデックスシグネチャのパラメータータイプは、 'string'または 'number'でなければなりません。

でも、それができインデックス型として使用します。私は最新のtypescriptバージョン(v3.7.2)を使用していますが、関連する質問が見つかりました:

typescriptシンボルのドキュメントも調べましたが、タイプとしてではなく、値としてどのように使用されるかを示しています。

例:

const obj = {} as {
    [key: number | symbol]: string // Won't work
};

const sym = Symbol('My symbol');
obj[sym] = 'Hi';

Microsoft / TypeScriptの問題

機能のリクエストを開く


TypeScriptは、オブジェクト型宣言で特定のシンボルのみをサポートしていると思います。あなたが本当にしたいです任意の symbol?多分あなたがあなたの使い方の例を示すでしょうtype obj-私はすべてのシンボルキー付きプロパティがstringsになるとは思いません。
ベルギ

@Bergi私は例を追加しました、おそらく何かを監督したかもしれませんが、tsにシンボルを受け入れるようにする方法を見つけることができません(anyこれは悪い習慣です)。
Simon


確信している権利が、あなたが使ってみた場合はいないですMap<Symbol,String>私たちは地図を持っているとして、それはあなたが達成しようとしているかの目的を果たすならば、
pavanクマール

私にとっても同じ問題ですが、「TSはJSのスーパーセットである」という誤った宣伝が不快な部分だと思います。これはその完璧な例です。
パトリック

回答:


3

残念ながら、現時点ではTypeScriptでこれを行うことはできません。これを期待する、または実際に記号をキーとして使用したいいくつかのAPIと相互運用する必要がある場合は、この厄介なバージョンを実行できます。

// Ensure we can not pass regular map to our custom functions
type SymbolMapTag = { readonly symbol: unique symbol }

type SymbolMap = SymbolMapTag & {
    [Key in string | number | symbol]: string;
}

function set_symbol<T extends SymbolMap, TSym extends symbol>
(target: T, sym: TSym, value: T[TSym]) {
    target[sym] = value;
}

function get_symbol<T extends SymbolMap, TSym extends symbol>
(target: T, sym: TSym): T[TSym] {
    return target[sym];
}

const symbol_map = {} as SymbolMap;

const sym = Symbol('My symbol');
set_symbol(symbol_map, sym, "hi");
get_symbol(symbol_map, sym); // string


type NonSymbolMap = {
    [Key in string | number]: string;
}

const non_symbol_map = {} as NonSymbolMap;
set_symbol(non_symbol_map, sym, "hi"); // error
get_symbol(non_symbol_map, sym); // error
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.