Gabriel Rubens Abreu
Astrocoders
Published in
2 min readFeb 15, 2019

--

Debora Cardenas (unsplash.com)

Edit: updated for JSX3 on June 5 2019

How to use ReasonML parametric types on a ReasonReact component

Suppose you have the following code (we are using genType to make our life easier here btw — we’ll post about it):


[@genType]
type state = {data: array(string)};
[@genType]
type renderItemBag = {
item: string,
index: int,
move: unit => unit,
moveEnd: unit => unit,
isActive: bool,
};
[@bs.module "react-native-draggable-flatlist"]
[@react.component]
external make:
(
~data: array(string),
~keyExtractor: string => string,
~scrollPercent: int,
~renderItem: renderItemBag => React.reactElement,
~onMoveEnd: state => unit,
array(React.element)
) =>
React.element =
"";
...Usage...<DraggableFlatList
data=[|"fubá", "corn", "cheese", "pork"|]
scrollPercent=15
renderItem=(MyItem.foo)
onMoveEnd=foo
/>

With this code you limit your users to have always “string” item type, but what if you want to give your user the ability to use any kind of item type? Parametric types to the rescue:

[@genType]
type state('item) = {data: array('item)};
[@genType]
type renderItemBag('item) = {
item: 'item,
index: int,
move: unit => unit,
moveEnd: unit => unit,
isActive: bool,
};
[@bs.module "react-native-draggable-flatlist"]
[@react.component]
external make:
(
~data: array('item),
~keyExtractor: 'item => string,
~scrollPercent: int,
~renderItem: renderItemBag('item) => React.element,
~onMoveEnd: state('item) => unit,
'a
) =>
React.element =
"";
...Usage now, anything!...<DraggableFlatList
data=[|"fubá", "corn", "cheese", "pork"|]
scrollPercent=15
renderItem=(MyItem.foo)
onMoveEnd=foo
/>...Usage...<DraggableFlatList
data=[|{ "name": "Bitcoin"}, {"name": "Ethereum"}|]
scrollPercent=15
renderItem=(({ item }) => <Item name={item ^ "foo"} />) /* compiler throws here as it detects item is not a string, it's a { . "name": string } */
onMoveEnd=foo
/>

The syntax for a parametric type goes as: type name('param) = foo;

You can even read it as a “parameter type to a type function”. And you can have as many as you want: type name('a, 'b, 'c, 'd) = ...;

Having the type parametric `item`and giving it the same name across params the compiler ensures for us that once it infers the first `‘item` all will follow the same type.

More examples of it in action:

https://github.com/reasonml-community/bs-react-native/blob/master/src/components/flatList.re#L51

--

--