2017-02-10 9 views
2

подписей Index в машинописном определены следующим образом:Машинопись - Как представлять указательный подпись в качестве общего типа

словарь

[key: string]: T 

Массив

[index: number]: T 

Они могут быть обернуты в некоторые простые , многоразовые типы:

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

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

Теперь я хочу обернуть их в один тип. Я попытался это:

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

Это не компилируется из-за следующей ошибки:

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

Разве это не возможно?

Какого черта?

Поскольку

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

выглядит аккуратнее, чем

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

В репозитории TypeScript есть проблема: https://github.com/Microsoft/TypeScript/issues/13398 Угадайте, что это еще не возможно. –

ответ

2

прохладный вопрос!
Я думаю, причина в том, что это действительно крайний случай для компилятора, который не был реализован, вероятно, потому, что он не стоит усилий.

Ключи свойств индекса могут быть только номерами, которые очевидны, а ключи свойств объекта могут быть только строкой или цифрами. Поэтому в конце ваше ограничение только указывает, что является фактом в любом случае, и что нужно будет обработать компилятором через специальный случай.
Так же я полагаю, что Сент-Андерс угробил, что усилия ;-)

, но почему бы не сделать это

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

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

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

Это не так аккуратно, как ваше решение, но в качестве компромисса, кажется, в порядке, специально как набор из типов XXXIndex ограничено 2