In github:jorgebucaran/hyperapp (can’t link because of max-2-links-per-post limitation), which also uses a virtualdom, the view is essentially a composed form of h()
and text()
.
h : (tag: String, props: Object, children: VNode? | [...VNodes]?) -> VNode
eg.,
h("label", {}, [
text("First name"),
h("input", {type: "text", value: "hello"}, [])
])
I am trying to type this h()
function. I have managed to make the basic stuff work. Playground link:
type vnode
@module("@hyperapp/html") @val external text: string => vnode = "text"
// props is essentially a plain object representing a set of html attributes.
type props
@obj external props: (~\"type": string=?, ~value: string=?, unit) => props = ""
@module("hyperapp") @val
external h: (string, props, array<vnode>) => vnode = "h"
let input = h(
"label",
props(),
[text("First name"), h("input", props(~\"type"="text", ()), [])],
)
I am stuck at trying to type the event handlers (onchange
, etc.) properties in props
.
eg., h("input", {onchange: [actionFn, payload], []})
, where
[actionFn, payload]
is an action descriptor;
actionFn
is
actionFn : (state, payload) -> | [state, ...effects] // returns a new state, with zero or more effects to be executed, OR
| [actionFn, payload] // returns an action descriptor to dispatch another action
Thus, the actionFn
returns either of the two tuples.
I have experimented a bit, but pasting those erroneous pieces of code here will make the post unecessarily long. Instead, let me link the playground.
So, how do I bind the h()
function, or rather how do I type props
? Any help is appreciated.