TypeScript:尝试使用字符串|时,索引签名参数必须为“字符串”或“数字”数

时间:2019-04-24 13:58:58

标签: typescript interface normalization

我正在尝试创建一个函数来规范化我的数组,并且期望一个结构如下的输出对象:

{
  allIds: [1],
  byId: {
    1: {...}
  }
}

OR

{
  allIds: ['1'],
  byId: {
    '1': {...}
  }
}

我正在尝试创建一个名为IOutput的接口来满足此要求。

我已经尝试过了:

interface IOutput {
  allIds: string[] | number[]
  byId: {
    [key: number | string]: any
  }
}

但这给了我以下错误

  

索引签名参数类型必须为“字符串”或“数字”。 ts(1023)

当我这样做时,它似乎起作用:

interface IOutput {
  allIds: string[] | number[]
  byId: {
    [key: number]: any
  }
}

OR

interface IOutput {
  allIds: string[] | number[]
  byId: {
    [key: string]: any
  }
}

但这不是我要完成的。我也试过了,它给了我同样的错误:

type StringOrNumber = string | number

interface IOutput {
  allIds: string[] | number[]
  byId: {
    [key: StringOrNumber ]: any
  }
}

我该如何完成我想做的事情?

1 个答案:

答案 0 :(得分:1)

这是当前我们编写索引方式的限制(这将更改soon enough)。索引签名参数只能是numberstring(正是那些类型,不能是它们的并集,不是文字类型)。但是,您可以有两个索引签名,一个用于number,一个用于string

还有另一个小窍门,如果您有string签名,则实际上也可以按number进行索引。因此,这意味着如果string索引和number索引具有相同的返回类型,则只需要字符串索引

interface IOutput {
    allIds: string[] | number[]
    byId: {
        [key: string]: any
        // [key: number]: any // Valid but not necessary
    }
}

let o: IOutput = {
    allIds: [1],
    byId: {
        1: {}
    }
}
let o2: IOutput = {
    allIds: ['1'],
    byId: {
        '1': {}
    }
}