Typescript 类型脚本联合类型一致性

Typescript 类型脚本联合类型一致性,typescript,union-types,data-consistency,Typescript,Union Types,Data Consistency,具有联合类型a type A = { b: true x: number } | { b: false x: string } declare const v: A 通过使用if判别块检查属性b值类型以保护类型A的一致性,我可以正确地将属性x分配给正确的类型 if (v.b) { // v.x is number // ok for compiler v.x = 3 // compiler error as v.x shou

具有联合类型
a

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

declare const v: A
通过使用if判别块检查属性
b
值类型以保护
类型A
的一致性,我可以正确地将属性
x
分配给正确的类型

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 = ''  
}
v.x = 3   // ok for compiler 
v.x = ''  // ok for compiler 
外部判别块
v.x
正确显示为
number | string

然而,编译器并不抱怨将
x
赋值给
number | string
,尽管这会破坏
类型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 = ''  
}
v.x = 3   // ok for compiler 
v.x = ''  // ok for compiler 
有没有办法强制编译器拒绝此选项?

在您的案例中,通用类型别名的代码示例:

好的,我想我已经找到了关于这一点的规范GitHub问题:,这是一个“不允许不安全的类型不兼容的赋值”的建议。这仍然是一个悬而未决的问题(截至2019-09-13),标记为“等待更多反馈”,因此,如果您认为您有一个引人注目的用例,但该用例中尚未提及,您可能希望在其中进行评论。不过,我不会屏住呼吸等待这项计划的实施,因为像和这样的相关问题要么已经结束,要么尚未采取行动

这里的问题涉及到类型系统缺乏可靠性。一个健全的系统只能让你做安全的事情。但在这里,它允许您对可能违反对象声明类型的对象进行属性分配。这种不安全的许可意味着类型系统不健全。这本身并不被认为是一个bug。它是“应用一个健全的或“可证明正确的”类型系统”。在正确性和生产力之间有一个折衷,很可能解决这个问题会带来更多的麻烦。有关TypeScript的可靠性和/或不足的更多讨论,请参阅

这里特别不合理的地方是:编译器假定可以安全地将同一类型写入可以从中读取的属性。如您的示例所示,这在一般情况下是不正确的,在以下情况下:


那么我们能做些什么呢?不确定。TypeScript 3.5引入了索引访问写入(例如
foo[bar]=baz
),因此如果键是联合类型(例如
bar
Math.random()虽然我确实认为这本身是一个有趣的问题,但同时这确实感觉像是一个问题,所以如果你能提供一些动机或背景来说明你想要实现的目标,也许这会很有用。也许你可以使用一种更合适的语法。你可以使用泛型类型别名:@apokryfos这是一个一般性问题,可以当开发人员仔细检查判别属性时,问题就简单地解决了……问题是,我希望TS编译器在编译时保持类型一致性——当类型定义好时,毕竟这是Typescript的主要目的之一……显而易见的情况是:开发团队正在处理一个涉及
typ的代码库我希望尽可能地消除运行时错误,我只是想知道是否有办法避免这个问题,或者它是否是一个Typescript函数lack@Oleg你能扩展一下你的建议吗?我的意思是,讨论了不健全的打字行为的一般情况,以及为什么不能消除它,但我不能确定它是否相关t到这个特定的实例。不幸的是,这不再是一个有区别的联合……或者根本不是联合。我假设这里的用例是,所讨论的变量必须是联合类型,并且不能通过注释来缩小范围。@aleclofabbro可以纠正我的错误。@jcalz指出的Oleg是另一个用例,不涉及一个联盟类型的人,谢谢你的深入解释。这让我对TS有了更好的理解和理解