为什么要对联合类型的类型保护进行判别?

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

在下面的代码中,为什么typeof data.x === 'string'类型防护不足以区分联合类型?

TS playground

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

function handler(data: A | B) {
    if (typeof data.x === 'string') {
        data.y // string | number --- WHUT?
    }
}

在什么情况下可以用(无效)形状handler调用{ x: string: y: string }

使用判别式,它起作用(为什么?):

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

function handler(data: A | B) {
    if (data.kind === 'A') {
        data.y // number
    }
}

阅读Discriminated Unions上的官方文档无济于事。

他们只说:

某些语言会自动为您区分工会;相反,TypeScript建立在当今存在的JavaScript模式上。

这不能解释为什么在某些情况下TS可以与类似的类型防护一起工作,而在没有工会的情况下(我在第一个示例中没有任何歧义)。

typescript discriminated-union union-types
1个回答
0
投票

被歧视的工会需要具有非常特殊的结构。我曾经挖过规则here

仅当在特定情况下将属性视为联合的判别式时,才可以缩小父对象。在以下情况下,一个属性被视为判别属性:

  • [属性是此处#9163概述的文字类型
  • 联合类型的属性如果具有至少包含一个单位类型且没有此处#27695概述的可实例化类型的联合类型,则为可判别的属性>

如果不遵循这些规则,则最终会导致字段歧视而不是父对象歧视。

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