gpt4 book ai didi

typescript 联合类型一致性

转载 作者:搜寻专家 更新时间:2023-10-30 21:00:42 24 4
gpt4 key购买 nike

拥有联合类型 A 的 Typescript 变量

type A = {
b: true
x: number
} | {
b: false
x: string
}

declare const v: A

我可以正确地将属性 x 分配给正确的类型,方法是使用 if 判别 block 检查属性 b 值类型以保护 type A一致性

if (v.b) {  // v.x is number

// ok for compiler
v.x = 3

// compiler error as v.x should be number
v.x = ''

} else { // v.x is string

// compiler error as v.x should be string
v.x = 3

// ok for compiler
v.x = ''
}

外部判别 block v.x 正确显示为 number |字符串
但是,编译器不会提示将 x 分配给 number | string 尽管这会破坏 type A 一致性

v.x = 3   // ok for compiler 
v.x = '' // ok for compiler

有没有办法强制编译器拒绝这个?
check it out on typescriptlang.org/play

最佳答案

好的,所以我想我已经找到了关于此的规范 GitHub 问题:microsoft/TypeScript#14150 ,建议“不应该允许不安全的类型不兼容的赋值”。它仍然是一个 Unresolved 问题(截至 2019 年 9 月 13 日),标记为“等待更多反馈”,因此如果您认为您有一个令人信服的用例尚未在其中提及,您可能想在那里发表评论。不过,我不会屏住呼吸等待实现,因为相关问题如 enforcing readonly strictness via flag flagenabling variance annotations已关闭或尚未采取行动。

这里的问题涉及类型系统缺乏健全性。健全的类型系统只会让你做安全的事情。但在这里它允许您对可能违反对象声明类型的对象进行属性分配。这种不安全的宽容意味着类型系统不健全。就其本身而言,这不被视为错误。是not one of TypeScript's design goals “应用健全的或‘可证明正确’的类型系统”。正确性和生产力之间存在权衡,解决这个问题很可能比它的值(value)更麻烦。参见 microsoft/TypeScript#9825有关 TypeScript 的健全性和/或缺乏健全性的更多讨论。

这里特别不可靠:编译器假定将相同类型写入到您可以读取的属性是安全的。这在一般情况下是不正确的,如您的示例和此 related example from the linked issue 所示:

interface A { kind: "A"; foo(): void; }
interface B { kind: "B"; bar(): void; }

function setKindToB(x: A | B): void {
x.kind = "B"; // clearly unsafe
}

那么可以做什么呢?不确定。 TypeScript 3.5 引入了一个 change索引访问写入(例如 foo[bar] = baz )以便如果键是联合类型(例如 barMath.random()<0.5 ? "a" : "b" )那么您必须将属性类型的交集写入它,而不是 union(所以 baz 的类型必须是 typeof foo.a & typeof foo.b 并且将不再接受 typeof foo.a | typeof foo.b )。这是一个健全性的改进,禁止了一些以前允许的无效的东西。而且它还禁止了许多以前允许的有效内容。很多人仍然对此感到不安,新的issues about it仍然相当频繁地提交。我想如果他们解决了这个问题,这里也会发生同样的问题……你会得到你期望的错误,而且很多代码库都会崩溃。现在我想说的是你应该避免做这些作业,我知道这并不是什么安慰。

无论如何,希望这些信息对您有所帮助。祝你好运!

关于 typescript 联合类型一致性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57924025/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com