wasm-bindgen icon indicating copy to clipboard operation
wasm-bindgen copied to clipboard

Support runtime union types with untagged enums

Open guybedford opened this issue 3 months ago • 2 comments

This extends enum support to work with singular untagged enums as a form of union type, allowing a representation for TypeScript union types using runtime generics in wasm bindgen.

Per standard generics, we treat JsValue as the target, then apply runtime checks to convert from JS into the appropriate type using the TryFromJsValue trait. Each tagged field of the enum is attempted in succession until one succeeds.

This is based to https://github.com/wasm-bindgen/wasm-bindgen/pull/4714 which extends all types into this runtime check, allowing for this implementation.

With this, it is possible to type JS functions like:

export function foo(a: "constant-string" | string | number | BigInt);

where we can write:

#[wasm_bindgen]
enum AEnum {
  ConstantString,
  String(String),
  Number(u32),
  BigInt(U64)
}

and have it work correctly for both directions of bindgen.

guybedford avatar Oct 10 '25 02:10 guybedford

Just to reflect some private concerns here: this seems like an extension of new syntax sugar that I know @daxpedda wanted to try and avoid in the core, so I'm going to defer to him for review.

E.g. once we land this, what if users might want all other Serde enum representations built into wasm-bindgen as well? It seems we might want to answer a question of where we draw a line between built-in serialization and things covered by serde-wasm-bindgen integration before adding features from said subset.

There are definitely valid reasons to add some integrations to the core, at least for optimisations alone as serde-wasm-bindgen doesn't have as much access to type information at compile-time as wasm-bindgen itself does, but we need to make sure we don't paint ourselves in the corner and on the hook for maintenance of even larger API area with all the semver difficulties that wasm-bindgen already comes with.

Maybe there are hooks we could expose instead to make tools like serde-wasm-bindgen more efficient or support more types, so that the core remains lean? I don't know the answer, but something worth exploring.


Offtop: what you're adding here is rather the untagged enums not tagged ones.

RReverser avatar Oct 17 '25 23:10 RReverser

CodSpeed Performance Report

Merging #4734 will not alter performance

Comparing enum-fallbacks (0f9ca45) with main (96f3e1e)

Summary

✅ 4 untouched

codspeed-hq[bot] avatar Dec 01 '25 06:12 codspeed-hq[bot]