6 ms·
> the Gleam aspect of this is inessential, TypeScript is quite good TypeScript can be quite productive but I find its type system lacking. Specifically the use
by wezm 3y ago
> the Gleam aspect of this is inessential, TypeScript is quite good
TypeScript can be quite productive but I find its type system lacking. Specifically the use of structural typing/lack of nominal typing and lack of sum types. I find these extremely useful when writing reliable software, which is why Gleam appeals to me.
- dcre 3y agoIt has sum types! Type unions with a discriminator.
- wezm 3y agoIt kinda does if https://www.typescriptlang.org/play#example/discriminate-types https://www.typescriptlang.org/play#example/discriminate-typ... is what you're referring to but it appears to be missing one of the major benefits: an error/warning if you haven't handled all variants. Edit: lots of replies showing how TypeScript can be made to do exhaustiveness checking. It's neat and all but it's a lot of gymnastics compared to languages that just have this built in, which again is part of the appeal of Gleam for me.
- superice 3y agoOh that’s easy to fake with type narrowing: function expectType<A, B extends A>() {} expectType<never, typeof yourUnion>(); The function call will fail at compile time if yourUnion is anything more than never, which you can use in your else case of if statements that narrow the discriminated union.
- dcre 3y agoYeah, that can be annoying. Until pattern matching makes it into JS, the main way people deal with this is to use a library. For example, ts-pattern lets you stick `.exhaustive()` at the end of a match call and I believe you get the error at typechecking time, not runtime. https://github.com/gvergnaud/ts-pattern https://github.com/gvergnaud/ts-pattern
- smj-edison 3y agoI ran into this exact issue when I was working on a piece of typescript that interoperates with a rust server, here's how I was able to do exhaustiveness checking (the errors aren't the prettiest, but it works): https://github.com/wwtos/mjuo/blob/main/vpo-frontend/src/lib/util/discriminated-union.ts https://github.com/wwtos/mjuo/blob/main/vpo-frontend/src/lib... EDIT: and an example of usage: https://github.com/wwtos/mjuo/blob/ca8c514185c1b5bb22aec752a4c41da0a50dcd4d/vpo-frontend/src/routes/node_editor/Node.svelte#L58 https://github.com/wwtos/mjuo/blob/ca8c514185c1b5bb22aec752a...
- laurencerowe 3y agoYou can workaround the lack of exhaustive matching with the following pattern: type Variant = { kind: "value", value: string } | { kind: "error", error: string } | { kind: "unexpected" }; class Unreachable extends Error { constructor(unexpected: never) { super(`${unexpected}`); } } function useVariant(variant: Variant) { switch (variant.kind) { case "value": return variant.value; case "error": return variant.error; default: throw new Unreachable(variant); } } The `new Unreachable(variant)` will fail the type check only when you have not exhaustively matched all variants.
- klavinski 3y agoFor the most straightforward nominative pattern matching, I would write a small match function: type A = { kind: "kindA", a: "dataA" } type B = { kind: "kindB", b: "dataB" } type Sum = A | B const match = < const V extends { kind: string }, const C extends { [ kind in V[ "kind" ] ]: ( value: V & { kind: kind } ) => unknown } >( value: V, cases: C ) => cases[ value.kind as V[ "kind" ] ]( value ) as ReturnType<C[ V[ "kind" ] ]> // You check the type of result, change the type of value to A or B, make the cases non-exhaustive... const howToUse = ( value: Sum ) => { const result = match( value, { kindA: _ => _.a, kindB: _ => _.b } ) } You can test it here: https://www.typescriptlang.org/play?#code/C4TwDgpgBAglC8UDeUDWBLAdgEwFxQCIMcYCAaKAQ3wO0uEtKgF8BYAKFEigCEFk0WPIWLYe5KACMadBuJYcu0AMoBXALb84AH14cOAYwD2mAM7Ao6+gYAW-ADwcozqMbMWAalAgAPYBBxTAVF8cwAnLABzFjInFzdzKABhbz8A7CCUAG1BHCgsKA8coiECKABdCvwACigAN0oAG1UIfC8AMmChfFEWKABKBAA+KFVMVEwjAHdMBXYh2obm1sKKA0pTCFN8FMH4EfXN0xylloA6Xo3C4tEyyvLFppaBqiCAJQhgVTDMABVwCD2JI5IoiUoVCpDfTsAD0MKgAE0jKpXDYIAZUFBgGisQCoEYAGZQMJbVSNYBrGyUTCRaDYul4wn1J50oywfFhXgUKyoOk4w5bKCTTAAWl8VNU5nQdQgZzlhhMiRs01+RgAqpt+I9lvg1Jo9iMkHFnAkLCTTGSLIgrMBbNqWhQjewXC7ctgYPgAPrDKCes6UWLO13OUQ8L0+v2SY19focZhAA https://www.typescriptlang.org/play?#code/C4TwDgpgBAglC8UDeU...
- Tade0 3y agoThat's by all design. Does this prevent you from writing reliable software?