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

Posted

技术标签:

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

这是我在 Stack Overflow 上的第一篇文章,所以我会尽力解释!我有这个名为短语的 JSON 文件。JSON:


  "start": 
    "affirmative": [
      some strings
    ],
    "interrogative": [
     some strings
    ]
  ,
  "mid": [
    some strings
  ]

所以我将它作为短语导入另一个文件,使用import phrases from '../utils/phrases.json',并在 modules.d.ts 中声明。

declare module '*.json' 
  const data: any
  export default data

我在导入phrases.json的文件中做了一个界面,就像这样:

interface Phrases 
  [key: string]: TypePhrases | string[]
  start: TypePhrases
  mid: string[]

interface TypePhrases 
  [key: string]: string[]
  affirmative: string[]
  interrogative: string[]

在我的课堂上,我创建了一个函数:

private getPhrases(position: string | number) 
    return phrases[position]
  

所以如果我在我的类中调用这个函数,如果我给出字符串'start',我想获得起始对象,或者如果我给出'mid',我想获得字符串数组,就像这样:

const MID_STRING: string = 'mid'
console.log(this.getPhrases(MID_STRING)[0])

但是在我的返回函数中,我得到了这个错误:

元素隐含地具有“任何”类型,因为类型的表达式 '字符串 | number' 不能用于索引类型 ' "start": “肯定”:字符串[]; “疑问”:字符串[]; ; “中”: 细绳[]; '。没有带有“字符串”类型参数的索引签名 在类型 ' "start": "affirmative": string[]; 上找到 “疑问”:字符串[]; ; “中”:字符串[]; '。

你能帮帮我吗?我尝试了很多东西,我不知道如何解决它...谢谢!

【问题讨论】:

phrases 是如何定义的? 帖子已用信息编辑 【参考方案1】:

导入对象的类型将由.json 文件中的对象而不是您定义的类型确定(我看不到两者之间的链接)。此外,declare module '*.json' 的定义也不是编译器使用的,因为它会在磁盘上找到文件。

你遇到的问题其实很简单。 Typescript 无法证明 phrase 是索引 phrases 的有效键。

您可以使用类型断言来实际使用您定义的类型:

private getPhrases(position: string) 
    return (phrases as Phrases)[position]


m() 
    const MID_STRING = 'mid'
    var a = this.getPhrases(MID_STRING); // a is TypePhrases | string[]
    if (a instanceof Array)  // must use type guard to index
        a[0]
    

Play

您还可以采取更安全的选择,并使用keyof 与泛型结合来实际获取对象中值的正确类型。这只有在您通常使用常量时才有可能。

private getPhrases<K extends keyof typeof phrases>(position: K) 
    return phrases[position]


m() 
    const MID_STRING = 'mid' // no string annotation, MID_STRING is typed as 'mid'
    this.getPhrases(MID_STRING)[0]; // ts knows this returns string[] and we can index iderctly into it

Play

如果你有一个string 你想用来索引一个类型,你也可以断言字符串是一个keyof 类型。这当然不是类型安全的,但有时是必要的:

private getPhrases(position: string) 
    return phrases[position as keyof typeof phrases]

【讨论】:

【参考方案2】:

数组索引应该是整数,而不是字符串

private getPhrases(phrase:string, position: number) 
    return phrase[position]
  

const MID_STRING: string = 'mid'
console.log(this.getPhrases(MID_STRING,0))

【讨论】:

短语在哪里??

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

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

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

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

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

TS7053:元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型“用户经济”

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