Hello,
I have been following the progress for more than a year, and last weekend I finally went ahead and tried to convert some functions in a Word file parser that is currently written in Flow.
I have a broad experience with JavaScript and TypeScript, but I’m still quite the noob when it comes to ReScript. I haven’t found an immediate answer to my question from reading the docs or searching the forum, but please tell me if I might have missed something.
I’m wondering how to idiomatically go from an array where items are typed as a variant (or union in TypeScript) to an array that has been filtered on one case of the variant, i.e. has its type narrowed.
To give a high-level description: a common pattern in my codebase is to start with an array where each item can have one of several types (typed in TypeScript as A | B | C
). I have understood that in ReScript, the correct type to use would be a variant.
In TypeScript, it is possible to filter the array with a type guard, such that the compiler can infer that the elements of the resulting array have had their types narrowed to one of A
, B
or C
.
In ReScript, however, I have tried modelling this with a variant type, switch
and Js.Array2.filter
— but I haven’t figured out how to let the compiler infer that the types have been narrowed.
type rec element = {
elements: array<element>,
name: string,
\"type": string,
}
type textElement = {text: string, \"type": [#text]}
type e = Element(element) | TextElement(textElement)
type argument = {
elements: option<array<e>>
}
/**
* Extracts text from a OOXML leaf element.
*
* @returns extracted text
*/
let default = ({ elements }: argument) => {
switch elements {
| Some(elements) =>
elements
->Js.Array2.filter(item =>
switch item {
| TextElement(item) => true
| _ => false
}
)
->Js.Array2.map(item => item.text) // `.text` is not allowed here
| None => undefined
}
}
Could someone please enlighten me?
Thank you!