How to strongly-type and and spread props (React)

I’ve got a React component and am using labeled parameters which is the recommended technique. Suppose this…

module Point = {
  @react.component
  let make = (~x:int, ~y:int) => <div />
}

Ok now imagine I want to define a function that returns properties that can be applied to that component. The react component includes a convenient function for making props but I can’t strongly type it without manually typing in the definition again.

let createRandomPointProps = () => {
   let result : ? = Point.makeProps(...)
   result
}

I know type inference makes this often unnecessary but in my case I’m defining a module where it is handy to be able to strongly type it. Like this…

module type PointDisplayer = {
  let getPointData : () => array<?>
}

Shouldn’t the react code include a type definition for props, like type props = { ~x:int, ~y:int }, in addition to the makeProps function, so the type definition can be used elsewhere? Second, and more importantly, once I’ve built an object using makeProps how do I spread the props into the component? This doesn’t work…

module Point = {
  @react.component
  let make = (~x: int, ~y: int) => <div />
}

module Line = {
  let z = Point.makeProps(~x=3, ~y=4)
  @react.component
  let make = () => <div> <Point {...z} /> </div> // does not compile
}

I can solve all these problems by NOT using labeled parameters on my React component and instead doing this. But this goes against the recommended approach.

module Point = {
  type props = {x: int, y: int}
  @react.component
  let make = (~p: props) => <div />
}

Hi @jmagaram

I believe that you may be able to do something like this:

let props = Point.makeProps(~x=0, ~y=0, ())
let element = Point.make(props)

As you might have seen, the type of props in this example resolves to:

{"x": int, "y": int}

Since this is an object with dynamic keys I believe its actual type is {..}

I suspect might need to declare a props type yourself if you need one:

module Point = {
  type props = {"x": int, "y": int}

  @react.component
  let make = (~x: int, ~y: int) => <div />
}

Thanks. Somehow I didn’t think about rendering my components like this…

<div>
{SomeComponent.make(SomeComponent.makeProps(...)}
</div>