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

时间:2017-09-04 19:28:54

标签: 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;
    }
}

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

var inverseMap: { [key: string | null]: number } = {};

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

var map = {};
map[null] = 3;
map[null];

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

3 个答案:

答案 0 :(得分:9)

无论信不信,JavaScript中的对象键始终是strings (好吧,或Symbols)。 (另见this answer)。当您将非字符串值作为键传递时,它会先被强制转换为字符串。所以,在

var map = {};
map[null] = 3;
map[null];

您实际上是在设置map["null"]。观察:

console.log(map["null"]===map[null]); // true

因此,在TypeScript中,他们主动决定only allow the string or number type as index signatures。可能是因为大多数时候,任何试图使用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;
}

请注意我们如何将source[i]强加给string,这让TypeScript感到高兴。如果你记得用String()包装密钥,只要你可以使用null,它应该适合你:

const inverseMap = buildInverseMap(['a', 'b', null, 'c']);
const aIndex = inverseMap['a'];
const nullIndex = inverseMap[String(null)];

希望有所帮助!祝你好运。

答案 1 :(得分:2)

执行map[null] = 3;与执行map['null'] = 3;具有完全相同的效果 因此,如果适合您,可以在打字稿中使用'null'

答案 2 :(得分:2)

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;

在typescript中,他们认为索引只能是stringnumber类型(虽然当使用数字作为键时它也会被转换为字符串),这就是为什么你有这些错误的原因

在你的情况下我会这样做:

inverseMap[source[i] || "null"] = i;