因此,我正在阅读Typescript的有关联合类型的官方文档,并且我认为它与F#中的“区分联合”相同(允许使用不同的语法,但是概念相同),因为我具有F#背景并且考虑到两者都得到了Microsoft的支持。但是从文档来看,F#并没有真正区分“工会类型”和“歧视工会”:https://fsharpforfunandprofit.com/posts/discriminated-unions/
但是,Typescript确实区分了这两个概念:
联盟类型:https://www.typescriptlang.org/docs/handbook/advanced-types.html#union-types
歧视联盟:https://www.typescriptlang.org/docs/handbook/advanced-types.html#discriminated-unions
所以我想知道这些概念本身是否真的有区别,还是仅依赖于某种语言的概念?
到目前为止,我了解的是F#中的联合类型也是区分联合,因为您可以使用匹配表达式和解构来区分联合类型。
但是,您不能使用Typescript进行区分,因为该语言没有提供执行此操作的特定表达式,因此您需要通过一个值来区分所有联合类型都具有的判别式。这是正确的吗?
答案 0 :(得分:5)
主要区别在于,Typescript Union Type实际上是F#区分Union的超集。
TypeScript联合类型= 未标记联合类型。
F#歧视联盟= 已标记联盟类型。
换句话说,每个可以用F#建模的有区别的联合都可以用Typescript联合类型同构地建模,但是反之则不成立。
例如,以下F#中的已区分联合:
type a' Option = Some of 'a | None
可以在Typescript中同构地建模为:
type Option<T> = {tag: 'Some', value: T} | {tag: 'None'}
但是,以下Typescript联合类型不能在F#中同构建模:
type UserInput = number | string
这里的主要区别是TypeScript联合类型不需要标记,但是F#联合类型必须被标记。
因此,我们可以看到TypeScript实际上比F#更灵活,但这并不是没有代价的,未标记的联合实际上是有漏洞的,这意味着在某些类型联合中TypeScript将无法进行类型检查。
这就像未类型的lambda演算是类型化的lambda演算的超集,但是类型lambda演算更容易证明正确。
答案 1 :(得分:2)
类型并集(A | B)
中的操作数都是两种类型,而有区别的并集type U = A | B
中的个案都是类型U
的构造函数,它们本身不是类型。类型U
的值在运行时被标记,因此您可以区分可能的情况。
一个结果是,可以以联合类型可能不会嵌套的方式嵌套已区分的联合。联合类型系统中某些类型A
的可选值可能表示为
type A? = (A | null)
其中null
是null
值的单例类型。
对于有区别的联合,通常表示为
type a' option = Some of 'a | None
使用此公式表示的值
let o: int option option = Some None
由于(A?)?
== (A | null) | null
== A | null
== A?