2017-10-23 94 views

Odpowiedz

3

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!

+0

Najlepsze rozwiązanie: 'StringIndexable' i' NumberIndexable' są dokładnie tym, co zrobiłem! Bardzo wszechstronny, dziękuję. – series0ne

5

Można ograniczyć TKey do wyprowadzenia z ciągu lub liczby (przy użyciu rozszerzeń), ale to nie zadowoli kompilatora. index musi być liczbą lub ciągiem znaków, a nie typem generycznym lub innym typem. Jest to udokumentowane w language spec