次のコードを考えると...
type Indexable<TKey, TValue> = { [index: TKey]: TValue }
これにより、次のエラーが発生します。
インデックス シグネチャ パラメーターの型は、'string' または 'number' でなければなりません。
TKey
「文字列」または「数値」に制約する方法はありますか?
次のコードを考えると...
type Indexable<TKey, TValue> = { [index: TKey]: TValue }
これにより、次のエラーが発生します。
インデックス シグネチャ パラメーターの型は、'string' または 'number' でなければなりません。
TKey
「文字列」または「数値」に制約する方法はありますか?
@ TitianCernicova-Dragomirが示すように、 orと同等TKey
であっても、インデックス署名の型として使用することはできません。string
number
TKey
それが正確にstring
またはであることがわかっている場合は、タイプでnumber
指定せずに直接使用できます。TKey
type StringIndexable<TValue> = { [index: string]: TValue }
type NumberIndexable<TValue> = { [index: number]: TValue }
余談: TypeScript の扱いは通常、キー型のnumber
一種のサブタイプとして扱われます。string
これは、JavaScript では、インデックスstring
を使用するとインデックスが変換され、次のような動作が発生するためです。
const a = { 0: "hello" };
console.log(a[0]); // outputs "hello"
console.log(a['0']) // *still* outputs "hello"
編集: TS2.9は、マップされた型のキーとキーさえもサポートするようにnumber
symbol
なったことに注意してください。keyof any
「お使いの TypeScript のバージョンが有効なキー タイプと見なすもの」という意味で使用します。残りの回答に戻ります。
特定のキーのみが許可されることを意味するより具体的にすることを許可TKey
する場合は、マップされた型を使用できます。keyof any
type Indexable<TKey extends keyof any, TValue> = { [K in TKey]: TValue }
文字列リテラルまたは文字列リテラルの結合を渡して使用しますTKey
。
type NumNames = 'zero' | 'one' | 'two';
const nums: Indexable<NumNames, number> = { zero: 0, one: 1, two: 2 };
type NumNumerals = '0' | '1' | '2';
const numerals: Indexable<NumNumerals, number> = {0: 0, 1: 1, 2: 2};
また、キーを特定のリテラルまたはリテラルの結合に限定したくない場合でも、string
as を使用できTKey
ます。
const anyNums: Indexable<string, number> = { uno: 1, zwei: 2, trois: 3 };
実際、この の定義は非常に便利で、 TypeScript 標準ライブラリにIndexable<TKey, TValue>
次のように既に存在します。Record<K,T>
type NumNames = 'zero' | 'one' | 'two';
const nums: Record<NumNames, number> = { zero: 0, one: 1, two: 2 };
したがってRecord<K,T>
、これらの目的で使用することをお勧めします。これは標準であり、コードを読む他の TypeScript 開発者はそれに精通している可能性が高いためです。
お役に立てば幸いです。幸運を!