【问题标题】:Type 'null' cannot be used as an index type类型“null”不能用作索引类型
【发布时间】:2018-02-13 01:09:12
【问题描述】:

我正在使用启用了严格的 null 检查的 Typescript。当我尝试编译以下代码时,我收到错误“type 'null' cannot be used as an index type。”

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

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

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

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

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

输出为 3。有没有办法在 Typescript 中实现这一点,或者 Typescript 不够聪明,无法做到这一点?

【问题讨论】:

  • 我有点惊讶您可以在 javascript 中设置一个“空”索引!我检查并成功了。我敢打赌它会给我带来某种错误。也许打字稿是逻辑,只是不允许这样做
  • 我认为这可能是一个错误。最初他们将索引参数限制为字符串,我猜当他们添加严格的空检查时并没有更改验证。

标签: typescript


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    不管你信不信,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 很高兴。如果您记得在可能将其与 null 一起使用时使用 String() 包装密钥,那么它应该适合您:

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

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

    【讨论】:

      【解决方案3】:

      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;
      

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

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

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

      【讨论】:

        猜你喜欢
        • 2023-01-31
        • 1970-01-01
        • 1970-01-01
        • 2021-12-16
        • 2017-10-05
        • 1970-01-01
        • 1970-01-01
        • 2023-01-20
        相关资源
        最近更新 更多