17

我正在使用 Typescript 并将一个小型库从 Javascript 转换为它。在代码的一个区域中,有一个静态定义的友好键名与其键码的映射。原始代码如下所示:

keys: { "Backspace": 8, "Tab": 9, "Enter": 13, ....etc.. };

我通过以下方式在打字稿中定义了这个:

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:字符串;1:字符串;2:字符串;4:字符串;8:字符串;9:字符串;: 细绳; }' 到 '{ [name: number]: string; }': '{ 0: string; 类型的索引签名 1:字符串;2:字符串;4:字符串;8:字符串;9:字符串;: 细绳; }' 和 '{ [name: number]: string; }' 不兼容

如何在 Typescript 中定义此映射?

4

3 回答 3

11

问题在于,在 JavaScript 中 - 因此在 TypeScript 中 - 对象文字的键始终是字符串,因此不能将其分配给具有数字索引器的变量。

带有数字索引器的对象是一个数组 - 所以你必须这样做:

var chars: string[] = [];
chars[8]= "Backspace";
chars[9]= "Tab";
chars[13] = "Enter";
于 2013-03-17T17:54:16.547 回答
2

实际上 js 内部只有基于字符串的索引(Array 与 {} 不同)但字符串/数字转换在 js 中是稳定的:

var x = {0 : "asdf",1:"bb"} 
alert(x[0])
alert(x[1])

我认为 typescript 也应该支持它并创建了一个可以投票的工作项:http: //typescript.codeplex.com/workitem/832

于 2013-03-19T05:58:14.923 回答
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...

Dictionary<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 添加到您的项目中。

希望有帮助。


* 我是古典团队的开发者之一

于 2014-10-22T10:23:02.213 回答