Modules as react props

I wonder if anyone else has had similar ideas.

Composition and extension can be a bit tedious at times, especially for components with many prop fields. It can also be error prone to compose components since optional fields can be omitted by accident.

module Lib = {
  type props = {
    a: string,
    b?: string
  }

  let make: React.component<props> = Js.Exn.raiseError("")
}


module NumericComponent = {
  type props = {
    a: string,
    b: float // formats a float nicely to a string
  }

  let make = (p: props) => Lib.make({a: p.a})
}

Are there any practical reasons why props is not a module instead?

They have support … for types via include.

module type P1 = {
  let a: string
  let b: string
}

module type P2 = {
  let b: float
}

module type P3 = {
  include P1
  include P2
}

Here is a full example.

module BaseComponent = {
  module type Props = {
    let name: string
    let age: int
    let height: int
  }

  let make = (module(P: Props)) => {
    open P
    <>
      {name->React.string}
      {age->Belt.Int.toString->React.string}
      {height->Belt.Int.toString->React.string}
    </>
  }
}

module Extension = {
  module type Props = {
    include BaseComponent.Props
    let height: float // new datatype for height
  }

  let make = (module(P: Props)) =>
    BaseComponent.make(
      module(
        {
          include P
          let height = height->Belt.Float.toInt
        }
      ),
    )
}

let comp = React.createElement(
  Extension.make,
  module(
    {
      let name = "John"
      let age = 42
      let height = 1.8
    }
  ),
)

let comp = <Extension
  {...module(
    {
      let name = "John"
      let age = 42
      let height = 1.8
    }
  )}
/>

The abilities of modules are available like functors.

I am unsure if anything akin to the ? modifier on types exists for modules (I would guess it’d equate to a default value for the field).

Syntatic work is needed to make it look as nice as jsx attributes. I don’t think that the equivalent of type parameters, abstract types, is inferrable, so that is another potential painpoint.