polyVariant to string?

Is there an accessor to get the name for a variant value as a string?
I dont see that in the docs.


A polyvariant compiles to a JavaScript string so there’s no need to convert it to a string.

I would like it as a string for use in other rescript.
My tab library uses strings for tab keys

I’ve used Obj.magic or external toString: polyVar => string = "%identity" before for this.

But I also saw some code that I didn’t actually understand recently: Safe binding for html <a> "rel" attribute - #5 by Hongbo (I couldn’t get it to compile and I’m not actually sure if it is relevant, but the code seemed to automagically convert polyVariants into strings)

a poly variant using @as(3) or with a parameter #Neat(int) arent represented as strings in js so seems like there could be more here.

Actually that comment from @JasoonS is a good hint.

Would this work for you?:

type color = [#red | #green | #blue]

// Coerce the polyvar to a string
let toString = (color: color): string => (color :> string)

let red = toString(#red)

There is also @deriving(jsConverter), which does exactly what you want, but for some reason all mention of it in relation to polyvariants has been removed from the docs. It works essentially the same as for normal variants.

1 Like

Check the first sentence of that page. They’ve been removed because they’re no longer recommended.

I tried your coercing example in the playground and it fails to compile with “Type color = [#blue | #green | #red] is not a subtype of string”.

Yeah I read that, but the OP was looking for exactly this functionality and we’re using it very happily!

yeah the playground isn’t updated yet. Soon!

Those accessors were stop-gap measures as we test the feasibility of compiling poly variant to strings and numbers. Now that they’ve shipped, the accessors ideally go away. Less runtime.

Ok makes sense, well in any case once this new :> operator is available then of course the accessors won’t be required!

1 Like

This is now officially released :slight_smile:

Playground Example

(Note: the coercion operator (:>) has always been part of the language. The change just allows polyvariants being coerced into its int or string representation)


This is a whole part of language I knew nothing about. It’s really hard to google – do you have any reason/ocaml links to relevant documentation? I didn’t even know subtyping was a thing in ocaml outside the object system.

Edit: found this in the ocaml manual.

It’s an item on our documentation todolist.

i think now it will be a little more relevant, so we might bump its priority for some new docs.

Somebody will want to try this anyway, so here goes :slight_smile:

(it’s about how to pattern match mixed string/int polyvariants)


It’s documented for poly variant here: Polymorphic Variant | ReScript Language Manual

Maybe one day for coercion of object too, but it’s not encouraged.

1 Like

Right. Understandably this is just an example, but at one point this is better off using regular variants. You’d eliminate like 3-4 concepts while improving readability too.

Heh, fair. Maybe the example was a bit pointless. But here’s a more relevant example that I could easily see useful in real life: stringifying a mixed polyvariant

I only pasted the first example because it took me a couple of minutes to figure out one needs to coerce twice to get to int/string. But it’s fine once you know it.

Looks like decoding some weird TS type: 1 | 2 | 3 | "foo" | "bar" | { id: string }. I mean, you probably wouldn’t want to create a type like this in ReScript, but you might have to deal with types like this in JS libs. Which might be a rule of thumb for normal variants vs polyvars: only use the latter for interop (well, maybe for composable errors too).