2017-10-23 3 views

Antwort

3

dokumentiert Wie @TitianCernicova-Dragomir zeigt an, Sie nicht TKey als Typ in einem Index Signatur verwenden können, auch wenn es equivalent to string or number ist.

Wenn Sie wissen, dass TKey genau string oder number, können Sie es einfach direkt verwenden und nicht TKey in Ihrer Art angeben:

type StringIndexable<TValue> = { [index: string]: TValue } 
type NumberIndexable<TValue> = { [index: number]: TValue } 

Neben: Es stellt sich heraus, dass in einem Bündel In TypScript muss der Indextyp für Eigenschaften eine string sein und nicht number. An solchen Stellen wird number üblicherweise als eine Art Subtyp von string behandelt. Das ist, weil in JavaScript, Indizes zu string ohnehin konvertiert werden, wenn Sie sie verwenden, um diese Art von Verhalten führen:

const a = { 0: "hello" }; 
console.log(a[0]); // outputs "hello" 
console.log(a['0']) // *still* outputs "hello" 

Da Sie nicht number im folgenden verwenden können, werde ich es ignorieren; Wenn Sie numerische Tasten verwenden müssen, wird TypeScript Sie wahrscheinlich erlauben, oder Sie können manuell zu string konvertieren.Zurück zu dem Rest der Antwort:


Wenn Sie TKey zulassen möchten spezifischere als string, was bedeutet, nur bestimmte Schlüssel sein dürfen, können Sie mapped types verwenden:

type Indexable<TKey extends string, TValue> = { [K in TKey]: TValue } 

Sie würden es verwenden, indem Sie ein Zeichenfolgenliteral oder eine Union von Zeichenfolgenliteralen für TKey übergeben:

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}; 

Und wenn Sie den Schlüssel nicht auf bestimmte Literale oder Vereinigungen von Literalen begrenzen möchten, können Sie immer noch string als TKey verwenden:

const anyNums: Indexable<string, number> = { uno: 1, zwei: 2, trois: 3 }; 

In der Tat, diese Definition für Indexable<TKey, TValue> so nützlich ist es existiert bereits in der TypeScript standard library as Record<K,T>:

type NumNames = 'zero' | 'one' | 'two'; 
const nums: Record<NumNames, number> = { zero: 0, one: 1, two: 2 }; 

ich Ihnen deshalb empfehlen Record<K,T> für diese Zwecke verwendet werden, da es Standard ist und andere TypeScript-Entwickler, die Ihren Code lesen, kennen ihn eher.


Hoffnung, die hilft; Viel Glück!

+0

Die beste Lösung: "StringIndexable" und "NumberIndexable" ist genau das, was ich getan habe! Sehr umfangreich, danke. – series0ne

5

Sie können festlegen, dass TKey von String oder Zahl abgeleitet wird (mit extends), aber das wird den Compiler nicht erfüllen. index muss entweder Nummer oder Zeichenfolge sein, nicht ein generischer Typ oder ein anderer Typ. Dies ist in der language spec