2017-02-10 2 views
2

signatures Index dactylographiée sont définies ainsi:tapuscrit - Comment représenter une signature d'index comme un type générique

Dictionnaire

[key: string]: T 

Tableau

[index: number]: T 

Ceux-ci pourraient être enveloppés dans quelques simples , types réutilisables:

type DictionaryIndex<T> = { 
    [key: string]: T 
} 

type ArrayIndex<T> = { 
    [index: number]: T 
} 

Maintenant, je veux les envelopper dans un seul type. J'ai essayé ceci:

type Index<TKey extends string|number, TValue> = { 
    [key: TKey]: TValue 
} 

Cela ne compile pas en raison de l'erreur suivante:

An index signature parameter must be of type 'string' or 'number'.

est-ce pas possible?

Pour quoi diable?

Parce que

foo(obj: Index<string, Bar>) 
foo(obj: Index<string, Bar> & Fooable<string>) 

regarde plus propre que

foo(obj: { [key: string]: Bar }) 
foo(obj: { [key: string]: Bar, canFoo: (foo: string) => Bar }) 
+0

Il ya un problème sur le repo TypeScript à ce sujet: https://github.com/Microsoft/TypeScript/issues/13398 Devinez ce n'est pas encore possible. –

Répondre

2

question cool!
Je pense que la raison en est que c'est vraiment un cas limite pour le compilateur qui n'a pas été implémenté probablement parce que cela n'en vaut pas la peine.

Les clés de propriété d'index ne peuvent être que des nombres évidents et les clés de propriété d'objet ne peuvent être que des chaînes ou des nombres. Donc, à la fin, votre contrainte indique seulement ce qui est un fait et ce qui devrait être traité par le compilateur via un cas spécial.
Encore une fois, je suppose que Saint Anders cet effort ;-) abandonné

mais pourquoi ne pas le faire

type StrIndex<TValue> = { 
    [key: string]: TValue 
} 

type NumIndex<TValue> = { 
    [key: number]: TValue 
} 

foo(obj: StrIndex<Bar>) 
foo(obj: StrIndex<Bar> & Fooable<string>) 

Il n'est pas aussi propre que votre solution, mais comme un compromis, il semble OK spécifiquement comme l'ensemble de XXXIndex types est limitée à 2