Rescript bindings for JSX.IntrinsicElements prop type
Tags: react, rescript, typescript, webdev
Published: 2022-08-04 08:02:00

Hi

In our workplace the react library relies heavily on typescript. Lately certain props have a type 
`keyof JSX.IntrinsicElements`

For example:

```
interface Props {
  ...,
  tagName?: keyof JSX.IntrinsicElements
}
```

Now how to pass this prop from the rescript side. After checking out the documentation https://www.typescriptlang.org/docs/handbook/jsx.html#intrinsic-elements and type definitions in @types/react/index.d.ts, I came up with polymorphic variant which would solve prop type issue.

```
module JSX = {
  module IntrinsicElements = {
    type t = [
      | #a
      | #abbr
      | #address
      | #area
      | #article
      | #aside
      | #audio
      | #b
      | #base
      | #bdi
      | #bdo
      | #big
      | #blockquote
      | #body
      | #br
      | #button
      | #canvas
      | #caption
      | #cite
      | #code
      | #col
      | #colgroup
      | #data
      | #datalist
      | #dd
      | #del
      | #details
      | #dfn
      | #dialog
      | #div
      | #dl
      | #dt
      | #em
      | #embed
      | #fieldset
      | #figcaption
      | #figure
      | #footer
      | #form
      | #h1
      | #h2
      | #h3
      | #h4
      | #h5
      | #h6
      | #head
      | #header
      | #hgroup
      | #hr
      | #html
      | #i
      | #iframe
      | #img
      | #input
      | #ins
      | #kbd
      | #keygen
      | #label
      | #legend
      | #li
      | #link
      | #main
      | #map
      | #mark
      | #menu
      | #menuitem
      | #meta
      | #meter
      | #nav
      | #noindex
      | #noscript
      | #object
      | #ol
      | #optgroup
      | #option
      | #output
      | #p
      | #param
      | #picture
      | #pre
      | #progress
      | #q
      | #rp
      | #rt
      | #ruby
      | #s
      | #samp
      | #slot
      | #script
      | #section
      | #select
      | #small
      | #source
      | #span
      | #strong
      | #style
      | #sub
      | #summary
      | #sup
      | #table
      | #template
      | #tbody
      | #td
      | #textarea
      | #tfoot
      | #th
      | #thead
      | #time
      | #title
      | #tr
      | #track
      | #u
      | #ul
      | #var
      | #video
      | #wbr
      | #webview
      | #svg
      | #animate
      | #animateMotion
      | #animateTransform
      | #circle
      | #clipPath
      | #defs
      | #desc
      | #ellipse
      | #feBlend
      | #feColorMatrix
      | #feComponentTransfer
      | #feComposite
      | #feConvolveMatrix
      | #feDiffuseLighting
      | #feDisplacementMap
      | #feDistantLight
      | #feDropShadow
      | #feFlood
      | #feFuncA
      | #feFuncB
      | #feFuncG
      | #feFuncR
      | #feGaussianBlur
      | #feImage
      | #feMerge
      | #feMergeNode
      | #feMorphology
      | #feOffset
      | #fePointLight
      | #feSpecularLighting
      | #feSpotLight
      | #feTile
      | #feTurbulence
      | #filter
      | #foreignObject
      | #g
      | #image
      | #line
      | #linearGradient
      | #marker
      | #mask
      | #metadata
      | #mpath
      | #path
      | #pattern
      | #polygon
      | #polyline
      | #radialGradient
      | #rect
      | #stop
      | #"switch"
      | #symbol
      | #text
      | #textPath
      | #tspan
      | #use
      | #view
    ]
  }
}


module Tile = {
  @genType.import("./Tile") @react.component
  external make: (
    ~tagName: JSX.IntrinsicElements.t
  ) => React.element = "Tile"
}
```

This is working fine. If anyone has a better suggestion please comment.