类型'null'不能用作索引类型

Aar*_*ron 8 typescript

我正在使用Typescript并启用了严格的空检查.当我尝试编译以下代码时,我得到错误"type'null'不能用作索引类型."

function buildInverseMap(source: Array<string | null>) {
    var inverseMap: { [key: string]: number } = {};
    for (let i = 0; i < source.length; i++) {
        inverseMap[source[i]] = i;
    }
}
Run Code Online (Sandbox Code Playgroud)

显然,逆映射不能将null作为键,因为类型约束不允许它.但是,如果我将inverseMap的类型更改为:

var inverseMap: { [key: string | null]: number } = {};
Run Code Online (Sandbox Code Playgroud)

我收到错误"索引签名参数类型必须是'字符串'或'数字'." 这很奇怪,因为在Javascript中使用null作为索引是合法的.例如,如果您在浏览器中运行以下代码:

var map = {};
map[null] = 3;
map[null];
Run Code Online (Sandbox Code Playgroud)

输出是3.有没有办法在Typescript中实现这一点,或者Typescript不够智能这样做?

jca*_*alz 9

无论信不信,JavaScript中的对象键始终是字符串(好吧,或者Symbols).(也见这个答案).当您将非字符串值作为键传递时,它会先被强制转换为字符串.所以,在

var map = {};
map[null] = 3;
map[null];
Run Code Online (Sandbox Code Playgroud)

你实际上是在设置map["null"].注意:

console.log(map["null"]===map[null]); // true
Run Code Online (Sandbox Code Playgroud)

因此,在TypeScript中,他们主动决定只允许stringnumber键入索引签名.可能是因为大多数时候,任何试图使用类似null内容索引到对象的人都表示错误.

在您的情况下,您可以这样做:

function buildInverseMap(source: Array<string | null>) : {[key: string] : number} {
    var inverseMap: { [key: string]: number } = {};
    for (let i = 0; i < source.length; i++) {
        inverseMap[String(source[i])] = i; // coerce to string yourself
    }
    return inverseMap;
}
Run Code Online (Sandbox Code Playgroud)

注意我们是如何强迫source[i]string自己,这让打字稿高兴.如果你记得在String()每次将它与null 一起使用时包装密钥,它应该适用于你:

const inverseMap = buildInverseMap(['a', 'b', null, 'c']);
const aIndex = inverseMap['a'];
const nullIndex = inverseMap[String(null)];
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!祝好运.


Nit*_*mer 7

Javascript 不允许nullundefined作为对象中的键,您不知道这一点,但您正在获取它们的字符串值,因此:

let a = {};
a[null] = "i am null";
a[undefined] = "i am undefined";
console.log(a[null] === a["null"]); // true;
console.log(a[undefined] === a["undefined"]); // true;
Run Code Online (Sandbox Code Playgroud)

在打字稿中,他们决定索引只能是stringand类型number(尽管当使用数字作为键时,它也会转换为字符串),这就是出现这些错误的原因。

对于你的情况我只会这样做:

inverseMap[source[i] || "null"] = i;
Run Code Online (Sandbox Code Playgroud)