Jak @TitianCernicova-Dragomir wskazuje, że nie można używać TKey
jako rodzaj podpisu w indeksie, nawet jeśli jest to equivalent to string
or number
.
Jeśli wiesz, że TKey
jest dokładnie string
lub number
, można po prostu użyć go bezpośrednio, a nie określenie TKey
w swoim rodzaju:
type StringIndexable<TValue> = { [index: string]: TValue }
type NumberIndexable<TValue> = { [index: number]: TValue }
Poza: Okazuje się, że w pęczek miejsc w TypeScript, typ indeksu dla właściwości musi być string
, a nie number
. W takich miejscach number
jest zwykle traktowany jako rodzaj podtypu z string
. To dlatego, że w JavaScript, indeksy są konwertowane do string
mimo to podczas korzystania z nich, co prowadzi do tego rodzaju zachowań:
const a = { 0: "hello" };
console.log(a[0]); // outputs "hello"
console.log(a['0']) // *still* outputs "hello"
Ponieważ nie można używać number
w dalszej części będę go ignorować; jeśli potrzebujesz użyć klawiszy numerycznych, TypeScript prawdopodobnie Ci pozwoli, lub możesz przekonwertować ręcznie na string
.Powrót do reszty odpowiedź:
Jeśli chcesz zezwolić TKey
być dokładniej niż string
, co oznacza tylko pewne klucze są dozwolone, można użyć mapped types:
type Indexable<TKey extends string, TValue> = { [K in TKey]: TValue }
Używałbyś go, przekazując literał łańcuchowy lub kombinację literałów łańcuchowych dla 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};
A jeśli nie chcemy ograniczać klucz do poszczególnych literałów lub związkom literałów, można nadal korzystać string
jak TKey
:
const anyNums: Indexable<string, number> = { uno: 1, zwei: 2, trois: 3 };
W rzeczywistości, ta definicja jest tak przydatne Indexable<TKey, TValue>
, to już istnieje w TypeScript standard library as Record<K,T>
:
type NumNames = 'zero' | 'one' | 'two';
const nums: Record<NumNames, number> = { zero: 0, one: 1, two: 2 };
dlatego zalecamy użycie Record<K,T>
do tych celów, ponieważ jest standardem i inni programiści TypeScript, którzy czytają twój kod, są bardziej zaznajomieni z nim.
Nadzieję, że pomaga; powodzenia!
Najlepsze rozwiązanie: 'StringIndexable' i' NumberIndexable' są dokładnie tym, co zrobiłem! Bardzo wszechstronny, dziękuję. – series0ne