Skip to content

JSX PPX - add Jsx.element return constraint #7722

@zth

Description

@zth

Components using @react.component/@jsx.component etc should always return JSX. But, there's currently nothing enforcing them to do that. In practice, they error as soon as they're used with other JSX (because JSX expects JSX), but the errors are quite cryptic, and it takes a while to understand that the problem is that you're not returning JSX from your component.

Therefore, we should add a type constraint for : Jsx.element to the return of the make function, via the JSX PPX. This will ensure type errors happen in the correct place, and we can probably special case those errors to include helpful information that all components need to return JSX.

Change should be to add : Jsx.element as return constraint for the make function in the JSX PPX. Example of how the output should look after having been processed by the JSX PPX:

// asyncAwait.txt
let f = a => Js.Promise.resolve(a + a)

module C0 = {
  @res.jsxComponentProps
  type props<'a> = {a: 'a}

-  let make = async ({a, _}: props<_>) => {
+  let make = async ({a, _}: props<_>): Jsx.element => {
    let a = await f(a)
    ReactDOM.jsx("div", {children: ?ReactDOM.someElement({React.int(a)})})
  }
  let make = {
    let \"AsyncAwait$C0" = (props: props<_>) => Jsx.promise(make(props))

    \"AsyncAwait$C0"
  }
}

module C1 = {
  @res.jsxComponentProps
  type props<'status> = {status: 'status}

  let make = async ({status, _}: props<_>) => {
    switch status {
    | #on => React.string("on")
    | #off => React.string("off")
    }
  }
  let make = {
    let \"AsyncAwait$C1" = (props: props<_>) => Jsx.promise(make(props))

    \"AsyncAwait$C1"
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions