5 ms·
Also Typescript https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types https://www.typescriptlang.org/docs/handbook/2/everyday-type...
by madeofpalk 2y ago
Also Typescript https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types https://www.typescriptlang.org/docs/handbook/2/everyday-type...
- fanf2 2y agoUnion types are not the same as sum types.
- dtech 2y agoTS narrows union types cases based on conditionals like "if" (called discriminated unions in the docs in the past), and supports exhaustiveness checks. How do they differ in functionality from sum types?
- mpawelski 2y agoSupports exhaustiveness checks only if you explicitly opt-in it (by coding to pattern where you use helper function that accepts `never` type). "Dicriminated Unions Type"/"Sum Types" feels very hacky there, at least syntax-wise, because it is constraint by being "JS + types" language. It's remarkable what Typescript can do, but having native Discriminated Unions in JS (hence in TS too) would be much more ergonomic and powerful.
- nyssos 2y agoSum types are disjoint unions. This `T` has three cases L = { tag: "a", payload: string } | { tag: "b", payload: number } R = { tag: "b", payload: number } | { tag: "c", payload: boolean } T = L | R whereas a proper sum type `L + R` would have four.
- brabel 2y agoIsn't that a completely useless distinction? For all purposes and intents, the "b" type in L and R should be treated the same, no? What do you gain by not doing that??
- hexane360 2y agoThis often comes up when writing a function which returns a wrapper over a generic type (like Option<T>). If your Option type is T | null, then there's no way to distinguish between a null returned by the function or a null that is part of T. As a concrete example, consider a map with a method get(key: K) -> Option<V>. How do you tell the difference between a missing key and a key which contains `null` as a value?
- brabel 2y agoThis is trivial to model by making your type `T | null | Missing`.
- efnx 2y agoMaybe trivial to “work around” but there is a difference, ay? With this type you would have to check/match an extra case! The type you use there also takes more memory than Option<T> or Maybe<T>. So it has some other downsides.
- epolanski 2y agoOr just using Option since you would have Some<null> or None in that case.
- hexane360 2y agoOnly if you're designing both functions ahead of time. In other words, it's not composable.
- epolanski 2y ago`T | null` is equivalent to T. You can assign null to `T`> It's like saying `string | "foo"` it is simply `string` due to subtyping.
- hexane360 2y ago... no? Unless you're referring to null as a bottom type, then that doesn't hold. Are you describing some property of a specific language?
- akavi 2y agoAs you've demonstrated, you can always construct sum types in typescript with the use of explicit discriminants: T = {tag: "L", payload: L} | {tag: "R", payload: R} The real issue is typescript doesn't have pattern-matching, which make operating on these sum types inelegant
- chem83 2y agoF# too. And Elm. But I get your point.