-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for C-Style Enums #31
Comments
Shouldn't be as TypeScript's support for sum types is pretty good (in some aspects better than Rust's one as it doesn't require explicit tags and so can cover any combinations of types). For example, enum MyEnum {
A,
B(u32),
C(u32, u32),
D { x: u32, y: u32 },
} could be translated to type MyEnum =
| { tag: 'A' }
| { tag: 'B', value: number }
| { tag: 'C', value: [number, number] }
| { tag: 'D', value: { x: number, y: number }
; |
Sounds great to me to support! I'd also be fine starting with C enums and moving from there to variants with payloads. I'd also be more than willing to help out with questions! I'm currently traveling now so I may be a bit slower but I'll help when I can. The bad news is that this support won't be trivial based on the current architecture but I don't think it'd be too hard to extend? |
This is a great idea! IMO for signature parity, the translated enum should be: type MyEnum =
| { A: any }
| { B: { '0': number } }
| { C: { '0': number, '1': number } }
| { D: { x: number, y: number } }
; |
@dbkaplun That would make it much harder to match on it in JavaScript code as it doesn't support match statements like in Rust (yet). While with separate tag/value representation you'll be able to do: function handleEnum(myEnum) {
switch (myEnum.tag) {
case 'A': ...; break;
case 'B': ...; break;
case 'C': ...; break;
case 'D': ...; break;
}
} or const myEnumHandlers = {
A() { ... },
B(value) { ... },
C([x, y]) { ... },
D({ x, y }) { ... }
};
function handleEnum(myEnum) {
return myEnumHandlers[myEnum.tag](myEnum.value);
} While it's possible to use something like |
I thought about your question earlier and it would be better to have a consistent interface than to pander to if (myEnum.A) {
} else if (myEnum.B) {
}
... |
@alexcrichton can you weigh in? |
At least in the Redux world this kind of enum (e.g., for things like Redux actions) are modeled in the tag/values approach. For example:
This works well and is easily modeled in plain JS or TypeScript. I think the other approach is fine, but I haven't seen it as much in the wild. Whatever the direction forward, I think it would be nice pick something familiar with JS devs. |
Consistent with what? There is no direct analogy to tagged enums in JS / TS either way. And Another reason for it would be that JS engines really don't like objects of different shapes (that is, different sets of properties) and would not be able to optimise any code using variables of such enum type. Also, as pointed above, this is already quite common for JS APIs to use |
I haven't thought too too hard yet about enums with payloads yet unfortunately, but I think we'd probably want to basically "see what JS does" in terms of what most closely matches Rust and then do that. |
Supporting the full power of Rust enums is probably a lot of work, but C-Style enums seem more doable. Is this something worth while tackling? If so, I would volunteer to help out (although I might need a bit of coaching).
The text was updated successfully, but these errors were encountered: