【问题标题】:Give unknown properties in an interface one type; give one known property a conflicting type为接口中的未知属性赋予一种类型;给一个已知的属性一个冲突的类型
【发布时间】:2020-03-10 03:18:45
【问题描述】:

我正在为表示 XML 元素的对象创建接口。我第一次看到的界面是这样的:

interface Mutation {
  [attribute: string]: string;
  children: Mutation[];
}

但是在编译这个的时候,TypeScript 出错了,告诉我Mutation[] 类型与string 类型冲突。所以,我想从[attribute: string]: string 中排除“children”属性:

interface Mutation {
  [attribute: Exclude<string, "children">]: string;
  children: Mutation[];
}

但是,这又报错了:索引签名参数类型不能是类型别名。考虑改写[attribute: string]: string | Mutation[]当然,这与目标背道而驰!

只允许在[attribute: string] 中输入Mutation[] 并不太难,比如[attribute: string]: Mutation[] | string。但这意味着每当我访问 Mutation 上的属性(“children”除外)时,我需要明确指出该值将是一个字符串 - 如果我将“children”之外的属性设置为Mutations 的数组!

有什么方法可以确保接口中的所有(未知)属性都是一种类型,同时为特定(已知)属性设置例外?

【问题讨论】:

标签: typescript


【解决方案1】:

很明显,Typescript 不喜欢这样,因为 children 的类型与 string 的通用索引类型不匹配。为了解决这个问题,拆分定义并使用联合类型将两种字段类型结合在一起。

type Mutation = { children?: Mutation[] } | { [attribute: string]: string };
const test: Mutation = {
  asdf: "adsf",
  children: [{
    qwerty: "qwerty"
  }]
};

【讨论】:

  • 这是一种有趣的方法,但它不会阻止{children: "someString"}。联合也没有像microsoft/TypeScript#17687 中建议的那样捕获“剩余索引签名”的意图。
  • 好点,我忘了测试children: string 案例。我想这个问题的解决方案取决于问题的真正含义。我可以看到在某些情况下,对象的形状确实是未知的,孩子可能是 string | Mutation[] 类型,否则应该有一个“已知”键的子集,它们都是字符串类型。
猜你喜欢
  • 2020-10-09
  • 1970-01-01
  • 2019-11-11
  • 2021-05-16
  • 2022-12-19
  • 2016-08-21
  • 2018-11-23
  • 2016-11-04
  • 2021-08-20
相关资源
最近更新 更多