类型缩小对于(几乎)受歧视的工会不起作用

问题描述 投票:0回答:1

给出以下类型定义:

type A = { a: string } | { a?: undefined; b: string }

这基本上意味着,如果您提供

a
,那就是您应该提供的全部。如果您没有提供
a
,或者您提供了
a
但它是
undefined
,您还必须提供
b

如果以下代码未定义

b
,我希望能够访问
a

let t = true
// The purpose in this line of code is to confuse the compiler such that it won't narrow the definition right in this line of code.
const z: A = t ? { a: 'a' } : { b: 'b' }

if (z.a) {
  console.log(z.a)
} else {
  console.log(z.b)
}

我收到的是以下错误消息::

Property 'b' does not exist on type 'A'.
  Property 'b' does not exist on type '{ a: string; }'

这里是 ts Playground 的链接,其中包含相关代码。

我期待一个类型安全的解决方案。即不使用不安全的字符串(例如

hasOwnProperty('b')
)来测试属性是否存在,并且不使用类型断言。

这可能吗?

typescript
1个回答
0
投票

我收到的是以下错误消息::

Property 'b' does not exist on type 'A'.
  Property 'b' does not exist on type '{ a: string; }'

您收到该错误消息的原因是,有可能进入 else 块并且仍然有

A
。如果
z.a
是空字符串
""
,就会发生这种情况。所以事实上在 else 情况下类型根本没有被缩小。

如果你将其切换到此,它将起作用:

if (typeof z.a === 'string') {
  console.log(z.a)
} else {
  console.log(z.b)
}

游乐场链接

© www.soinside.com 2019 - 2024. All rights reserved.