Как определить число-> строковый словарь в Typescript?
Я играю с Typescript и конвертирую через небольшую библиотеку к нему из Javascript. В одной области кода было установлено статически определенное сопоставление имени дружественного ключа с их ключевым кодом. Исходный код выглядел так:
keys: { "Backspace": 8, "Tab": 9, "Enter": 13, ....etc.. };
Я определил это в Typescript через:
static keys: { [name: string]: number; } = { "Backspace": 8, "Tab": 9, "Enter": 13, ... etc.. };
Это работает нормально, однако в другой части кода используется противоположное отображение:
chars: {8:"Backspace",9:"Tab",13:"Enter", ...etc... };
Итак, я попытался сделать тот же тип определения в Typescript, что я сделал ранее:
chars: { [code: number]: string; } = { 8: "Backspace", 9: "Tab", 13: "Enter", ...etc.. };
Не удается выполнить компиляцию со следующей ошибкой:
Невозможно преобразовать '{0: string; 1: строка; 2: строка; 4: строка; 8: строка; 9: строка;: string; } 'to' {[имя: номер]: строка; } ': Индексные подписи типов' {0: string; 1: строка; 2: строка; 4: строка; 8: строка; 9: строка;: string; } 'и' {[имя: номер]: строка; } 'несовместимы
Как определить это сопоставление в Typescript?
Ответы
Ответ 1
Проблема заключается в том, что в JavaScript - и, следовательно, в TypeScript - ключи объектного литерала всегда являются строками и поэтому не могут быть назначены переменной с индексом числа.
Объект с индексом числа - это массив - и поэтому вы должны это сделать:
var chars: string[] = [];
chars[8]= "Backspace";
chars[9]= "Tab";
chars[13] = "Enter";
Ответ 2
Здесь находится библиотека под названием Classical.js *, которая может помочь вам выполнить эту и подобные проблемы. Он, в частности, определяет двуязычный словарь. Для вашего варианта использования код будет выглядеть так:
import c = Classical.Collections;
var keys = new c.Dictionary<string, number>();
keys.add("Backspace", 8);
keys.add("Tab", 9);
keys.add("Enter", 13);
//etc...
keys.getValue("Backspace"); //8
keys.getValue("Tab"); //9
keys.getValue("Enter"); //13
//etc...
Словарь < TKey, TValue > работает со всеми типами объектов и не имеет проблем с конфликтами имен, такими как ключи с именем "конструктор".
Для противоположного отображения вы можете либо построить инверсный словарь, либо запросить текущий так:
keys.query().single(pair => pair.key === 8).value; //"Backspace"
keys.query().single(pair => pair.key === 9).value; //"Tab"
keys.query().single(pair => pair.key === 13).value; //"Enter"
//etc...
Если вы хотите попробовать, посетите Classical, откройте папку bin и добавьте classic.js и classic.d.ts в ваш проект.
Надеюсь, что это поможет.
* Я один из разработчиков классической команды
Ответ 3
Действительно, js внутренне содержит только индексы на основе строк (при этом Array отличается от {}), но преобразование строк и чисел является устойчивым в js:
var x = {0 : "asdf",1:"bb"}
alert(x[0])
alert(x[1])
Я думаю, что typescript также должен поддерживать его и создать рабочий элемент, на который вы можете проголосовать: http://typescript.codeplex.com/workitem/832