TypeScript-元素隐式地具有“ any”类型,因为类型“ string”的表达式不能用于索引类型

tes*_*est 3 javascript typescript

假设我有这个:

const color = {
    red: null,
    green: null,
    blue: null
};

const newColor = ['red', 'green', 'blue'].filter(e => color[e]);
Run Code Online (Sandbox Code Playgroud)

错误在color[e]底部附近:

元素隐式地具有“ any”类型,因为类型“ string”的表达式不能用于索引类型“ {red:null; 绿色:null;蓝色:null;}'。在类型“ {{red:null;}”上找不到带有参数“ string”的索引签名。绿色:null;蓝色:null;}'。

我尝试在TypeScript文档上到处查找,但是我interface对此到底想怎么想,以便它可以接受color[e]

hug*_*ugo 48

您可以声明colorsasany告诉 TypeScript 放弃这个(又名显式 any):

const color : any = {
    red: null,
    green: null,
    blue: null
};
Run Code Online (Sandbox Code Playgroud)

但如果可能,最好使用强类型:

const color : { [key: string]: any } = {
    red: null,
    green: null,
    blue: null
};
Run Code Online (Sandbox Code Playgroud)

有关 TypeScript 中索引的更多信息:索引签名


编辑:这个对类似问题的回答中,作者建议使用Map<,>-- 如果这适合您的用例。

  • `{ [key: string]: 任意 }`..?TypeScript 为您提供了“Record&lt;string, any&gt;”类型。 (14认同)

Cél*_*lia 18

我知道这是一个老问题,但我对其他答案不满意。请as尽可能避免使用该关键字!

让我们看看为什么会遇到这个错误以及如何处理它。

原因:const 和字符串数组都没有类型。

当您没有为 const 指定类型时,Typescript 会根据初始值推断其类型。知道这一点后,错误只是说“嘿,e可以是任何字符串,甚至是不属于 const 推断类型的字符串”。e如果等于推断类型'yellow'中未知的值怎么办color

我可以向您推荐 3 种方法来处理此问题:

1.最简单但不那么“ Type script Spirit”的解决方案

只需string为 const 的键指定一个类型,如下所示:

const color: {[key:string]:null} = {
  red: null,
  green: null,
  blue: null
};
Run Code Online (Sandbox Code Playgroud)

嗯……这可行,但我们可以做得更好。

2.正在打字的路上...

告诉 Typescript 编译器您正在使用const 的推断类型的键和关键字 : 。keyof typeof

在给定的示例中,这将是:

const colorKeys: (keyof typeof color)[]  = ['red', 'green', 'blue'];

const newColor = colorKeys.filter((e) => color[e]);
Run Code Online (Sandbox Code Playgroud)

你还能再多努力一点吗?请参阅下一点。

3. 就是这样:为你的对象指定类型!

创建一个接口(或任何您需要的类型)并将其赋予您的 const。然后,使用关键字指定字符串数组的类型keyof

interface Color {
  red:number|null;
  green:number|null;
  blue:number|null;
}
const color: Color = {
  red: null,
  green: null,
  blue: null
};

const colorKeys: (keyof Color)[]  = ['red', 'green', 'blue'];

const newColor = colorKeys.filter((e) => color[e]);
Run Code Online (Sandbox Code Playgroud)


jca*_*alz 5

您遇到的问题不是那color是错误的类型,而是TypeScript推断了['red', 'green', 'blue']be 的类型string[]。通常,这种类型的推断是可取的,因为(对于所有编译器都知道)您可能希望继续推论'purple'。但是,在这种情况下,你想编译器知道的唯一成员是三个字符串文字'red''green''blue'。也就是说,您需要至少与特定的类型Array<'red'|'green'|'blue'>

假设你正在使用TS3.4或更高版本,最简单的方法来获得这种类型推理的编译器是使用const断言

const constAssertionTest = ["red", "green", "blue"] as const;
// const constAssertionTest: readonly ["red", "green", "blue"];
Run Code Online (Sandbox Code Playgroud)

as const导致编译器来推断一个元组正是数组中的三个字符串文字组成的,在你设置的确切顺序。(它甚至是一个只读的元组)。这足以解决您的错误:

const newColor = (['red', 'green', 'blue'] as const).filter(e => color[e]); // okay
Run Code Online (Sandbox Code Playgroud)

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

链接到代码


Pra*_*das 5

感谢所有精彩的答案。打字稿新手,成功解决了我的第一个障碍。

  // in javascript world this is what I used to do.
  let values1 = products.reduce((acc, product) => {
      acc[product] = 1;
  //  ^  --> Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
  // No index signature with a parameter of type 'string' was found on type '{}'.  TS7053

      return acc;
  }, {})

  // in typescript world I needed an extract type specification for 'acc'
  let values2 = products.reduce((acc: { [key: string]: number}, product) => {
      acc[product] = 1; //No more error
      return acc;
  }, {})
Run Code Online (Sandbox Code Playgroud)