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.tinstead ofDom.cssStyleDeclarationto get a fully typed style object. - You could just assume
nodeListcontains onlyhtmlElements in yourforEachbinding, or if you want more flexibility, add a genericnodeListOftype, 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.