Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Something I am absolutely missing from TypeScript is enums with associated data like in Rust: https://doc.rust-lang.org/reference/items/enumerations.html.

The usefulness of this obviously depends on pattern matching control flow ops in Rust that don't exist in TypeScript but it would make my life just so much easier.



You can do a similar thing with discriminated unions in TS, with some caveats mainly around ergonomics. You can even get exhaustiveness checking with a little trickery

Edit, example of exhaustiveness checking:

  switch(obj.kind) {
    case "one": return ...
    case "two": return ...
    case "three": return ...
    default:
      // @ts-expect-error
      throw Error("Didn't cover " + obj.kind)
  }
This will actually err at compile time if you missed a case, because otherwise obj.kind will have type "never", which will cause a type error on that line, which will be expected due to the directive comment. If obj.kind is not "never", the code will not have an error, and so the directive will cause an error.

...it is definitely preferable having language-level support for this stuff though.


In most situations you don't even need a default case: https://tsplay.dev/NlpBGN


That's what union types are.

Actually, in practice I find TS union types much more useful than Rust enums, because you can mix and match options in different combinations freely. In Rust, you can't use one of the enum variants as a type on it's own, and I had to tediously create a lot of wrapper types that I didn't in TS.


They are not the same feature. Enums allows you to create new values, while union types only allow you to combine values. For example, in Rust, enum Toto { Titi, Tata } would create a new type, Toto, that contains two values, Toto::Titi and Toto::Tata. There's no way to express that with union types.

On the other hand, Rust's enum have to be defined before use: I can't suddently decide to have a function that returns "Toto" | "Tata" without creating a type or returning string.

OCaml has something called "polymorphic variants" that seem to be a middle-ground between the two: https://ocaml.org/manual/polyvariant.html.


Help me understand this feature. How does it differ from a discriminated union of object types? (I might be completely misunderstanding the feature you’re raising)


TS discriminated unions are functionally nearly identical to variants in OCaml and enums in Rust. I don't know about Rust, but the difference between TS and OCaml is mainly just the syntax and ergonomics. OCaml has great syntax for pattern matching and exhaustiveness checking, for example. You can still get this functionality in TS with if/else or switch statements and potentially some type system tricks: https://www.fullstory.com/blog/discriminated-unions-and-exha...

To illustrate how TS discriminated unions are functionally equivalent, check out this playground link showing how ReScript (an alternate syntax of OCaml which can compile to JavaScript) compiles an OCaml variant to a JavaScript object with a "TAG" key that could easily be typed as a discriminated union in TypeScript:

https://rescript-lang.org/try?code=C4TwDgpgBAThCOBXCBnYBlYBD...




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: