DEV Community

Srikanth Kyatham
Srikanth Kyatham

Posted on

Rescript bindings for Typescript union types

Hi

Typescript has a beautiful concept of combining different types for a given interface attribute/variable/parameter etc.
Rescript is more strict you can have only one type for a given attribute/variable/parameter. So in this post, I would like show on how to create a union type in Rescript which would be accepted by typescript as well.

Let's assume we have a prop type, which accepts string | number.

interface Props {
  ...otherProps,
  badgeContent: string | number
}

Enter fullscreen mode Exit fullscreen mode

In rescript side we have to come up with module which would wrap Number and String like this

@unboxed
type rec t = Any('a): t

module String_or_number: {
  type t
  type case =
    | Number(float)
    | String(string)
  let number: float => t
  let string: string => t
  let classify: t => case
} = {
  @unboxed
  type rec t = Any('a): t
  type case =
    | Number(float)
    | String(string)
  let number = (v: float) => Any(v)
  let string = (v: string) => Any(v)
  let classify = (Any(v): t): case =>
    if Js.typeof(v) == "number" {
      Number((Obj.magic(v): float))
    } else {
      String((Obj.magic(v): string))
    }
}

Enter fullscreen mode Exit fullscreen mode

The usage of the String_or_number type

module Badge = {

  @genType.import("./Badge") @react.component
  external make: (
    ...,
    ~badgeContent: String_or_number.t=?,
  ) => React.element = "Badge"
Enter fullscreen mode Exit fullscreen mode

In case we want to pass number to badgeContent then we use it as follows

<Badge badgeContent=String_or_number.number(1.0) />
Enter fullscreen mode Exit fullscreen mode

Top comments (0)