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

Posted

技术标签:

【中文标题】TypeScript - 元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型【英文标题】:TypeScript - Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 【发布时间】:2019-12-17 16:13:38 【问题描述】:

假设我有这个:

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

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

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

元素隐含地具有“任何”类型,因为类型的表达式 'string' 不能用于索引类型 ' red: null;绿色:空;蓝色: 空值; '。没有带有“字符串”类型参数的索引签名 在类型 ' red: null; 上找到绿色:空;蓝色:空; '。

我尝试在 TypeScript 文档上到处寻找,但我怎么会认为 interface 这个可以接受 color[e]

【问题讨论】:

【参考方案1】:

您可以将 colors 声明为 any 以告诉 TypeScript 放弃这个(又名 explicit any):

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

但如果可能的话,强类型更可取:

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

更多关于 TypeScript 索引的信息:Index Signatures


编辑:在this answer 的类似问题中,作者建议使用Map<,>——如果这适合您的用例。

【讨论】:

[key: string]: any ..? TypeScript 为您提供了 Record<string, any> 类型。【参考方案2】:

感谢所有出色的答案。 typescript 新手并成功解决了我的第一个障碍。

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

【讨论】:

【参考方案3】:

您遇到的问题不是 color 是错误的类型,而是 TypeScript 将 ['red', 'green', 'blue'] 的类型推断为 string[]。通常这种类型的推理是可取的,因为(编译器都知道)您可能想将'purple' 推到它上面。但在这种情况下,您希望编译器知道唯一的成员是三个字符串文字'red''green''blue'。也就是说,您需要一个至少与 Array<'red'|'green'|'blue'> 一样具体的类型。

假设您使用的是 TS3.4 或更高版本,从编译器获取这种类型推断的最简单方法是使用 const assertion:

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

as const 导致编译器推断出一个 tuple,该 tuple 完全由数组中的三个字符串文字组成,按照您设置的确切顺序。 (甚至是read-only tuple)。这足以解决您的错误:

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

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

Link to code

【讨论】:

以上是关于TypeScript - 元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型的主要内容,如果未能解决你的问题,请参考以下文章

Typescript 元素隐式地具有任何类型,带有 for...in 循环

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

Object.keys 迭代导致 Typescript 错误“元素隐式具有‘任何’类型,因为索引表达式不是‘数字’类型”

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

映射打字稿参数:绑定元素“列”隐式具有“任何”类型

元素隐式具有“任何”类型,因为类型“窗口”没有索引签名?