简体   繁体   English

TypeScript - 元素隐式具有“任意”类型,因为“字符串”类型的表达式不能用于索引类型

[英]TypeScript - Element implicitly has an 'any' type because expression of type 'string' can't be used to index type

I have this code:我有这段代码:

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

const newColor = ['red', 'green', 'blue'].filter(e => color[e]);

The error is in color[e] near the bottom with the error:错误在底部附近的color[e]中,错误为:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ red: null;元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型“{ red: null; green: null;绿色:null; blue: null;蓝色:null; }'. }'。 No index signature with a parameter of type 'string' was found on type '{ red: null;在类型 '{ red: null; 上找不到参数类型为 'string' 的索引签名green: null;绿色:null; blue: null;蓝色:null; }'. }'。

I tried looking everywhere on TypeScript docs, but how am I supposed to interface this so it can accept color[e] ?我试着在 TypeScript 文档上到处寻找,但我应该如何interface它以便它可以接受color[e]

You can declare colors as any to tell TypeScript to get off your back on this one (aka explicit any ):您可以将colors声明为any以告诉 TypeScript 摆脱这个(又名显式 any ):

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

But if possible, strong typing is preferable:但如果可能,最好使用强类型:

const color : { [key: string]: any } = {
    red: null,
    green: null,
    blue: null
};

More information on indexing in TypeScript: Index Signatures有关 TypeScript 中索引的更多信息: 索引签名


EDIT: In this answer to a similar question, the author suggest using a Map<,> -- if that fits your use-case.编辑:这个对类似问题的回答中,作者建议使用Map<,> -- 如果这适合您的用例。

The problem you're having is not that color is the wrong type, but that TypeScript is inferring the type of ['red', 'green', 'blue'] to be string[] .您遇到的问题不是color类型错误,而是 TypeScript 将['red', 'green', 'blue']的类型推断为string[] Often that type of inference is desirable, since (for all the compiler knows) you might want to push 'purple' onto it.通常,这种类型的推理是可取的,因为(对于所有编译器而言)您可能想要将'purple'推到它上面。 But in this case, you'd like the compiler to know that the only members are the three string literals 'red' , 'green' , and 'blue' .但在这种情况下,您希望编译器知道唯一的成员是三个字符串文字'red''green''blue' That is, you need a type at least as specific as Array<'red'|'green'|'blue'> .也就是说,您需要一种至少与Array<'red'|'green'|'blue'>一样具体的类型。

Assuming you're using TS3.4 or later, the easiest way to get this kind of type inference from the compiler is to use a const assertion :假设您使用的是 TS3.4 或更高版本,从编译器获得这种类型推断的最简单方法是使用const断言

const constAssertionTest = ["red", "green", "blue"] as const;
// const constAssertionTest: readonly ["red", "green", "blue"];

The as const causes the compiler to infer a tuple composed of exactly the three string literals in the array, in the exact order you've set. as const使编译器按照您设置的确切顺序推断由数组中的三个字符串文字组成的组。 (It's even a read-only tuple ). (它甚至是一个只读元组)。 That is good enough to fix your error:这足以解决您的错误:

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

All right, hope that helps.好的,希望有帮助。 Good luck!祝你好运!

Link to code 代码链接

I know it is an old question but I'm not satisfied by the other answers.我知道这是一个老问题,但我对其他答案不满意。 Please avoid the as keyword as much as possible !请尽量避免使用as关键字!

Let's see why we encounter this error and what to do with it.让我们看看为什么会遇到此错误以及如何处理它。

Reason: neither the const nor the array of strings have a type.原因:const 和字符串数组都没有类型。

When you do not give a type to a const, Typescript infers its type based on the initial value .当你不给 const 一个类型时,Typescript 会根据初始值推断它的类型。 Knowing that, the error just says "hey, e could be any string, even strings that are not part of the inferred type of your const".知道这一点,错误只是说“嘿, e可以是任何字符串,甚至是不属于您的 const 推断类型的字符串”。 What if e was equal to 'yellow' that is not known in color inferred type?如果e等于color推断类型中未知的'yellow'怎么办?

I can recommend you 3 ways to handle this:我可以向您推荐 3 种处理方法:

1. Simplest but not so " Type script Spirit" solution 1. 最简单但不那么“ Type script Spirit”的解决方案

Just give a type string to the keys of your const, like this:只需为 const 的键提供一个类型string ,如下所示:

const color: {[key:string]:null} = {
  red: null,
  green: null,
  blue: null
};

Hmmm... That works, but we can do better.嗯……这行得通,但我们可以做得更好。

2. On the way to types... 2. 在打字的路上...

Tell Typescript compiler you are using the keys of the inferred type of the const with the keywords: keyof typeof .告诉 Typescript 编译器您正在使用 const 的推断类型键和关键字: keyof typeof

In the given example, that would be:在给定的示例中,这将是:

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

const newColor = colorKeys.filter((e) => color[e]);

Can you still make a little extra effort?你还能再努力一点吗? See next point.见下一点。

3. Here it is: give types to your objects ! 3. 就是这样:给你的对象赋予类型!

Create an interface (or whatever you need as a type) and give it to your const.创建一个接口(或任何你需要的类型)并将其提供给你的常量。 Then, specify the type of the array of strings with the keyof keyword:然后,使用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]);

Thanks for all the great answers.感谢所有伟大的答案。 New to typescript and successfully fixed my first road block.打字稿新手并成功修复了我的第一个障碍。

  // 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;
  }, {})

Here's another solution using Record这是另一个使用Record的解决方案

const color: Record<string, null> = {
    red: null,
    green: null,
    blue: null
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型 React Typescript - Element implicitly has an 'any' type because expression of type 'string' can't be used to index type React Typescript TypeScript - ts(7053):元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引 - TypeScript - ts(7053) : Element implicitly has an 'any' type because expression of type 'string' can't be used to index TypeScript 错误:“元素隐式具有 'any' 类型,因为类型 'any' 的表达式不能用于索引类型 - TypeScript Err: "Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型“BGColors” - Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'BGColors' 元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型“{}” - Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}' 元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型 - Phaser - Element implicitly has an 'any' type because expression of type 'string' can't be used to index type - Phaser 元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型“{ AT: number; BE:数字,...}` - Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ AT: number; BE: number,…}` 元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型 A - Element implicitly has an 'any' type because expression of type 'string' can't be used to index type A 元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型样式 - Element implicitly has an 'any' type because expression of type 'string' can't be used to index type style 如何修复 Element 隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型? - how fix Element implicitly has an 'any' type because expression of type 'string' can't be used to index type?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM