为什么联合类型的类型保护需要判别式?
Why is a discriminant needed for type guards of union types?
在下面的代码中,为什么 typeof data.x === 'string'
类型保护不足以区分联合类型?
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?
}
}
在什么情况下可以使用(无效)形状 { x: string: y: string }
调用 handler
?
使用判别式,它有效(为什么?):
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 上的官方文档没有帮助。
他们只声明:
Some languages automatically discriminate unions for you; TypeScript instead builds on JavaScript patterns as they exist today.
这并不能解释为什么 TS 在某些情况下可以使用类似的类型保护,而在联合的情况下却不能(我在第一个示例中没有看到任何歧义)。
有区别的工会需要有一个非常特殊的结构。我曾经挖出规则 here:
Narrowing the parent object is only done in specific scenarios, when the property is considered a discriminant for the union. A property is considered as a discriminant property if:
如果不遵守这些规则,您最终会得到字段歧视,而不是父对象歧视。
在下面的代码中,为什么 typeof data.x === 'string'
类型保护不足以区分联合类型?
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?
}
}
在什么情况下可以使用(无效)形状 { x: string: y: string }
调用 handler
?
使用判别式,它有效(为什么?):
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 上的官方文档没有帮助。
他们只声明:
Some languages automatically discriminate unions for you; TypeScript instead builds on JavaScript patterns as they exist today.
这并不能解释为什么 TS 在某些情况下可以使用类似的类型保护,而在联合的情况下却不能(我在第一个示例中没有看到任何歧义)。
有区别的工会需要有一个非常特殊的结构。我曾经挖出规则 here:
Narrowing the parent object is only done in specific scenarios, when the property is considered a discriminant for the union. A property is considered as a discriminant property if:
如果不遵守这些规则,您最终会得到字段歧视,而不是父对象歧视。