The DOM types that ship with the compiler are pretty bare bones, but here’s a couple of suggestions to make it a bit easier:
- You can use
JsxDOMStyle.t
instead ofDom.cssStyleDeclaration
to get a fully typed style object. - You could just assume
nodeList
contains onlyhtmlElement
s in yourforEach
binding, or if you want more flexibility, add a genericnodeListOf
type, similar to what TypeScript has.
Here’s the equivalent piece of code implementing those two suggestions:
type nodeListOf<'a>
@send external forEach: (nodeListOf<'a>, 'a => unit) => unit = "forEach"
@scope("document") external querySelectorAll: string => nodeListOf<Dom.htmlElement> = "querySelectorAll"
@get external style: Dom.htmlElement => JsxDOMStyle.t = "style"
let trace: 'a. ('a, string) => 'a = (value, msg) => {
Console.log(msg)
Console.log(value)
value
}
let main: unit => unit = () => {
let elements = querySelectorAll(".abc")
elements->forEach(el => {
let style = el->style->trace("converted record ")
style.zIndex->Console.log
let style = {...style, zIndex: "1"}
})
}
main()
Also, on a more technical point, {..}
is an object type, not a record type. And your cssStyleToRecord
function is not soundly typed, because the returned object type will be inferred from use, that is, it will be assumed to have whichever fields you use from it. You should generally avoid object types. It’s more of a historical artifact.