属性不能分配给接口中的字符串索引

dev*_*054 16 interface typescript typescript2.0

我有以下接口:

export interface Meta {
  counter: number;
  limit: number;
  offset: number;
  total: number;
}

export interface Api<T> {
  [key: string]: T[];
  meta: Meta; // error
}
Run Code Online (Sandbox Code Playgroud)

目前,我收到以下错误:

'Meta'类型的属性'meta'不能赋予字符串索引类型'T []'.

搜索了一下之后,我在TS文档中找到了这个声明:

虽然字符串索引签名是描述"字典"模式的有效方式,但它们还强制所有属性都与其返回类型匹配.这是因为字符串索引声明obj.property也可用作obj ["property"].

这是否意味着当我有一个字符串索引签名时,我不能没有匹配此类型的任何其他变量?

实际上我可以摆脱这个错误声明这样的界面:

export interface Api<T> {
  [key: string]: any; // used any here
  meta: Meta;
}
Run Code Online (Sandbox Code Playgroud)

这样做,我失去了类型推断的完全能力.没有这种丑陋的方式,有没有办法做到这一点?

Sar*_*ana 16

您可以使用两个接口的交集:

interface Api<T> {
    [key: string]: T[];  
}

type ApiType<T> = Api<T> & {
    meta: Meta;
}

declare let x: ApiType<string>;

let a = x.meta // type of `a` is `Meta`
let b = x["meta"]; // type of `b` is `Meta`

let p = x["someotherindex"] // type of `p` is `string[]`
let q = x.someotherindex // type of `q` is `string[]`
Run Code Online (Sandbox Code Playgroud)

  • 这似乎是一个更基本的问题的解决方法:TypeScript接口没有像JSON Schema那样的“ additionalProperties”机制。您的解决方案在“定义”类型时有效,但在“实现”类型时失败。在您的示例中,尝试为x分配一个值,例如x = {meta:new Meta(),someotherindex:['abc']}`。您会得到一个错误。我会发布一个指向TypeScript Playground的链接,但是这样的评论太长了。 (5认同)
  • @tokland:初始化时您忘记为“x”分配类型。当为其分配类型“ApiType&lt;string&gt;”时,您应该会收到错误消息。 (2认同)

小智 6

当我尝试实现此接口时,提供的最佳解决方案不起作用。我最终用动态键嵌套了部分。也许有人会发现它很有用:

interface MultichannelConfiguration {
  channels: {
    [key: string]: Configuration;
  }
  defaultChannel: string;
}
Run Code Online (Sandbox Code Playgroud)