【发布时间】:2020-08-03 10:15:28
【问题描述】:
考虑类型FooBar1和FooBar2定义如下:
type Foo = { foo: string };
type Bar = { bar: number };
type FooBar1 = Foo & Bar;
type FooBar2 = { foo: string; bar: number };
问题:FooBar1和FooBar2有什么区别?
我的尝试/研究:
- 它们可以双向分配给彼此!
(手动检查并使用
tsd- see here) - 不过,它们彼此并不相同! (检查
tsd- see here) - VSCode 的智能感知不会自动将
{ foo } & { bar }折叠成{ foo, bar },但它确实会将其他复杂类型折叠成更简单的形式,例如将NonNullable<string | undefined>折叠成string:
// |------------------------------------------------------------|
// | let x: { |
// | a: string; |
// | } & { |
// | b: string; |
// | } |
// | -----------------------------------------------------------|
// ^
// | When hovering `x` here:
// |
let x: { a: string } & { b: string };
编辑: Difference between extending and intersecting interfaces in TypeScript? 已被建议重复,但我不同意。我不是将交集与接口的扩展进行比较,而是将交集与另一种原始类型进行比较,不涉及接口或扩展。
【问题讨论】:
-
在注意到两票结束后,我编辑了问题,使其更简单、更切题。希望这些选票现在可以撤回。让我知道我是否应该改进其他任何事情。
-
您使用哪个 typescript 编译器版本?使用
3.8.3编译时不会出现预期的警告(您在 Github 上的尝试)。 -
@WolverinDEV 嗨,谢谢,是的,我也使用 3.8.3,它可以编译,是的,但编译不是问题。
-
我很确定这是 TSD 中的一个错误,它只是无法确定这两个是相同的。
-
tsd使用来自tsc的isTypeIdenticalTo来检查两种类型是否相同,但是检查变得非常复杂非常快,所以我没有检查为什么这两种类型不相同。当前的语言版本没有定义这种关系,因此向语言用户询问可能不是一个相关的问题,它只是一个编译器细节。编译器使用一些标志来区分 Object 和 Intersection 类型。这种区别可能与“补码类型”之类的东西相关(例如 not (A & B) == not A | not B)
标签: typescript types