元素隐式具有“ any”类型,因为类型为string |数字不能用于索引类型

时间:2019-08-08 09:12:02

标签: typescript

这是我关于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
}

我在导入的文件中创建了一个接口,就像这样:

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])

但是在返回函数中,出现此错误:

  

元素隐式地具有“ any”类型,因为类型的表达式   '字符串|数字”不能用于索引类型“ {”“开始”:{   “肯定”:string []; “疑问”:string []; }; “中”:   串[]; }'。没有带有“字符串”类型参数的索引签名   在类型'{“开始”:{“肯定”:字符串[]上找到   “疑问”:string []; }; “ mid”:string []; }'。

能帮我吗?我尝试了很多事情,我不知道该如何解决...谢谢!

2 个答案:

答案 0 :(得分:2)

导入对象的类型将由.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]
}

答案 1 :(得分:0)

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

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

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