4 ms·
When I see this it makes me want to run for ReasonML/ReScript/Elm/PureScript. Sum types (without payloads on the instances they are effectively enums) should n
by cies 2y ago
When I see this it makes me want to run for ReasonML/ReScript/Elm/PureScript.
Sum types (without payloads on the instances they are effectively enums) should not require a evening filling ceremonial dance event to define.
https://reasonml.github.io/ https://reasonml.github.io/
https://rescript-lang.org/ https://rescript-lang.org/
https://elm-lang.org/ https://elm-lang.org/
https://www.purescript.org/ https://www.purescript.org/
(any I forgot?)
It's nice that TS is a strict super set of JS... But that's about the only reason TS is nice. Apart from that the "being a strict super set" hampers TS is a million and one ways.
To me JS is too broken to fix with a strict super set.
- dkersten 2y ago> (any I forgot?) Gleam has real sum types and can compile to JS. https://gleam.run/ https://gleam.run/
- cies 2y agoIndeed! I thought it was BEAM only...
- spankalee 2y ago> It's nice that TS is a strict super set of JS... But that's about the only reason TS is nice. I mean, yes, exactly?? That's TypeScript's entire reason for being, and it's no small thing. I use TypeScript where I would have used plain JavaScript. If I have a reasonable choice of an entirely different language - ie, I'm not targeting browsers or Node - then I would definitely consider that. I personally haven't seen that any compile-to-JS language is worth the interop tax with browsers or the JS ecosystem, and I've built very complex apps on GWT and used to be on the Dart team working on JS interop.
- Freedom2 2y agoCivet (https://civet.dev https://civet.dev) is probably my favorite one if I want something a bit fancier than Typescript, purely because it shares the same elements that you are as "opt-in" as much as you like, at least in my limited experience.
- hombre_fatal 2y agoOn the other hand, pasting the `type ValueOf<T> = T[keyof T];` idiom into your TS code so you can use it for your enums is a hell of a lot less ceremony than ditching TS for any of the languages you listed. Especially when you can still just us TS enums if you wish. And on top of that, each of them has a whole new collection of ceremonies you're going to have to learn. All for what, to avoid `as const`?
- pjmlp 2y agoThat single reason is all that matters, because it maps directly to what the platform actually understands, instead of adding another layer to debug.
- ninetyninenine 2y agoTS sum types are actually more powerful thanks to 'as const' These are dependent types which none of the languages above can enable. Meaning the type system can actually read values in your code and create types from the code. This is not inferring the type, this is very different. For example: const PossibleStates = ["test", "me"] as const type SumTypeFromArray = (typeof PossibleStates)[number] let x: SumTypeFromArray = "this string triggers a type error as it is neither 'test' nor 'me'" So in TS you can actually loop through possible states while in ML style languages you would have to pattern match them individually.
- int_19h 2y agoTS does have sum types, so you can already do something like: type Color = "red" | "green"; What GP is doing is some scaffolding on top to make the values more discoverable and allow associating arbitrary Color-specific metadata with them.
- davorak 2y agoI thought there were edge cases where sum types were not fully supported, nesting[1] is the example found first, but I thought there were others. [1] https://github.com/microsoft/TypeScript/issues/18758 https://github.com/microsoft/TypeScript/issues/18758
- int_19h 2y agoPer the comments there, it still works if you use an explicit type guard function for checks, as opposed to checking the nested property directly, so I'd argue that the type itself is still supported in general, just not this particular way of testing for one of the options.
- davorak 2y agoMaybe I am doing something wrong but when I fill in a concrete value for `aOrB` I still get a type error in that example code: Playground Link: https://www.typescriptlang.org/play/?#code/C4TwDgpgBAglC8UDeAoK6qkgLmWjBAdgIYC2EuARDJfugL51TG6ECupARhAE4qMos0AEII8BIblQEiZClErDaBRgU6sO3PgIDGAe0IBnYMwDyPYbjgAfKKMTSMk8TPQlyVJU3oAaJuqgARn4AbhQUfSMTYnNhQ1wAChs7AEoAbQBdMTSmR1dnPNcMd3lFZSLfJjVcYJU-DLCIg2MzCwAmMRiLQzSABgbwgHpBqF4ePR5mQ1GAD0gdYBQASwAzKASu4QA6IS2ShHhEakoU5ChhqCXSMAAbJZ0l4BuQKHJiI0wAC2ITAANN36Xaa-JCYcDyUElKg0KD0ei-JiRQx6G4QLY3PQAcw2sS2xFOFwAojxxtpwis2IQFksDFBvoYACrggBycgAPKzyLNgBBCAATabGHhLQiYgB8GykYJwZyhUCFIsxsN8UDlnIgKVwxCBZwKqrkuHVypc6B4EGAbB4hGYO3BezkB0QJX44VW63pTMg6pxFh8ChoKVOoIuEDmdweTxebw+wG+fwBOpB0oh+o8-soyoRBCRKLRGOxmzxBJGYwmdN40GI0wA7hAbjcXcs1gkPSy5D64n0Mn7joGziGw-dHs9XhB3tNYz8oP9YoClsDQXq5cdM4jmrn0ViOz1+kXziNCHpRiSJo23S2q56IN7Nm0ewGg-vZrch5HR+OvlOZxY5wvk1LlxhOEswwHNUU3AtYjaPcLmZI9S20IA https://www.typescriptlang.org/play/?#code/C4TwDgpgBAglC8UDe... I tried with 5.8.2 and nightly and the results were the same. Interestingly, the playground reports aOrB(from github comment with concrete value) and aOrB2(modified) as the same type, `A | B`, but aOrB will give an error in the typeguarded if block but aOrB2 does not trigger an error. I do not know what is going on there either they do not really have the same type despite the playground reporting both as `A | B` or there is different bug going on. So the solution presented in github does not look like a full solution as is.