【问题标题】:Provide one of object types in typescript在打字稿中提供一种对象类型
【发布时间】:2018-04-29 03:31:12
【问题描述】:

如果我输入以下内容:

interface A {
    x: number
}
interface B {
    y: number
}

type Z = A | B;

// here it allows me to create a variable of type Z with both members of type A and B.
let z: Z = {
    x: 5,
    y: 6,
}

我无法确保 Z 类型的对象确实包含 A 的所有成员,但不包含 B 的成员(或相反)。 TypeScript 有可能吗?经过大量研究,我倾向于“否”的答案,但我不确定。

【问题讨论】:

标签: typescript types object-literal


【解决方案1】:

默认情况下,联合将所有提供的选项合并为一个,但您有两个选项。 TypeScript 中没有你想要的东西,但是 TS 项目的列表中存在类似的问题(状态:此时为“打开”)以及两个很好的解决方法。

一个选项不可用:目前 TypeScript 中没有确切的类型 (unlike in Flow)。有一个 TS 问题 #12936 "Exact Types",目前仍处于开放状态。

TS 的未决问题列表中还有另一个问题/建议,它准确地询问了您的问题:#14094 "Proposal: Allow exclusive unions using logical or (^) operator between types"

您可以使用以下解决方法:

选项 #1

在 TypeScript 和 Flow 中,您可以使用标记类型来创建 XOR 联合而不是 OR 联合。

interface A {
    kind: 'A',
    x: number
}
interface B {
    kind: 'B',
    y: number
}

type Z = A | B;

// here it DOES NOT allow to create a variable of type Z with both members of type A and B.
let z: Z = {
    kind: 'A',
    x: 5
    // y: 6 will produce an error
}

选项 #2

第二个选项是设置所有类型的所有属性,但将那些不应该存在的设置为undefined

interface A {
    x: number,
    y?: undefined
}
interface B {
    x?: undefined,
    y: number
}

type Z = A | B;

let z: Z = {
    y: 5
    // y: 6 will produce an error
}

作为记录,在 Facebook 的类型系统 Flow 中,您可以通过使用 不相交联合 (XOR) 而不仅仅是联合 (OR) 或使用精确的对象类型或作为对于上面的 TS,将不需要的属性设置为 undefinedI made a Flow demo with your example (link)。在这种情况下,Flow 的代码与 TS 的代码相同。

【讨论】:

  • 也许我遗漏了什么,但我不认为这个例子说明了 OP 的问题:这个例子在z 中使用 only members from interface A ,这是对联合类型的期望(给定| 的典型符号)。我认为当您混合使用 AB 时会出现混淆。
  • @msanford 我被你的困惑弄糊涂了,这正是它解决的问题。尝试使用 BOTH 会出现错误。
  • 在最后一个示例中,您复制了“在这里它允许我创建一个类型为 Z 的变量,其中包含类型 A 和类型 B 的成员”。是的,它没有,它只有A 的成员。也许我会找到一个更能说明问题的例子。
  • ...正如您刚刚添加的那样。 :) 我仍然觉得包含该行令人困惑,因为实施不相交的联合防止你这样做。
  • 第一个解决方法是黄金,完全解决了我的情况!我在 TypeScript 文档中阅读了有关“可区分联合”的信息,因为该名称听起来不错,但文档没有说明在使用判别字段时,突然不允许来自其他接口的字段。这是一种丑陋的结构,但我很高兴它有效。顺便说一句,TS 中有一些尝试制作过滤器和/或减法类型,它们可能允许相同但不使用判别字段。
猜你喜欢
  • 2021-03-13
  • 2022-09-29
  • 1970-01-01
  • 2021-04-18
  • 1970-01-01
  • 2021-02-04
  • 1970-01-01
  • 2020-10-11
  • 1970-01-01
相关资源
最近更新 更多