Is there a way to convert a type to values?
My use case is that I have this type:
type rgb = [ #Red | #Green | #Blue ]
And I’d like to force the user to choose between one of the three in a dropdown.
Is there a way to convert a type to values?
My use case is that I have this type:
type rgb = [ #Red | #Green | #Blue ]
And I’d like to force the user to choose between one of the three in a dropdown.
If it is a string value that you want to convert to then, Polymorphic variants without any parameters, actually compiles to a string. You can check this playground link (check the js output).
However it is better to deliberately convert it using a function like this.
let convertToString = (rgb: rgb) =>
switch rgb {
| #Red => "Red"
| #Green => "Green"
| #Blue => "Blue"
}
Thanks, I am doing something similar to that now.
My question was more if it’s possible to convert the entire type to a string array without having to type each case
You can actually do
let rgbToStr = (x: rgb) => {
(x :> string)
}
but I think @mellson is looking for generating a set/list of available variants.
I don’t think if it’s possible without using a ppx.
Thanks @amiralies - you’re right I was looking for a way to convert. But a ppx would be overkill, I was just trying to see if I was missing some built-in functionality
Does it have any advantage over external rgbToStr: rgb => string = "%identity"
?
I take it you don’t care about localization? Because automatic conversion is obviously not i18n-friendly.
The :>
(coercion) operator only works when the type of lefthand side is subtype of righthand so
if you add a case to your variant which is not subtype of string (for example #Other(string)
) you will get a type error.
Got a solution working
If I add @deriving(jsConverter)
to the enum there’s a free string to enum convertor.
Then we just iterate all the words and voila we have converted the type into values.
@deriving(jsConverter)
type rgb = [#Red | #Green | #Blue]
let allTheKnownWordsInTheUniverse = [...]
let rgbValues = allTheKnownWordsInTheUniverse->Array.map(rgbFromJs)->Array.keep(Option.isSome)
There’s a few performance reasons before I put it into production though