[hdom] ideas/plans about typing hdom?
It will be nice to have hdom typed, something like:
type HElement = (
["div", ({ style? : string } | HElement)?, ... HElement[]] |
["canvas", ({ width? : number, heigth? : number } | HElement)?, ... HElement[]]
)
For this, emmet style tags like "tag#id.class1.class2" needs to be sacrificed, but I think is a good tradeoff. Do you have any plans about this?
Hi @nahuel - that's an issue which is partially been discussed in the past and I'm of several minds about it. First some refs to some prev context:
- https://github.com/thi-ng/umbrella/issues/140#issuecomment-544494226
- https://github.com/thi-ng/umbrella/issues/140#issuecomment-544555688 (& onwards)
To add: If hiccup/hdom trees would only consist of simple elements, then your above approach could of course work (by now, pre-TS3.7 we couldn't even do recursive tuple types...), but it's also very common for component trees to include:
- ES6 iterables (not just arrays) - which should then be typed/have generics as well
- Component objects with hdom's
ILifecycleinterface - Types which implement the
IDerefinterface - either as element children or as attrib values - Lazy evaluated component functions in this form:
[func, ...arbitraryArgs]
Also, currently any other value is allowed in the tree, but will be cast to string...
Finally, there's currently a lot of work underway on a new version/alt approach under the working title hdom2020 and you can follow along with progress on this feature branch and/or on the #umbrella channel in our Discord (link in main readme header). Be warned though, there're no docs yet and only a single example published so far... FWIW the approach in that new version will be more typed, but is also somewhat different (not entirely) to the current hdom...
I think if you (and others) really struggle with the untyped approach for your components, why don't use the "Call method B" described in that first comment linked above (which will give you full type safety) or create some typed helper functions to at least type check parts of your tree in your above mentioned manner. IMHO either of these two (or a combination) would be much more pragmatic and useful than attempting to define a single type definition which covers all of the above supported cases (which actually are used in the wild) and then also still plays nicely with all sorts of custom component types one might define.
Thanks for the detailed response, I will go with the typed helper functions approach!
Cool. Also, am really not meaning to close the door on a more typed approach, just wanting to emphasize that:
- an alternative is slowly emerging (with yet not fully understood consequences)
- it's essential to fully support the above mentioned value types which can be or be included in a hypothetical
HElement - the loss of Emmet-style tags would be potentially problematic for various people (incl. me), but possibly livable if there're some real tangible other benefits (which I personally don't really see, yet :)
I think it would be reasonable to just allow any value for unknown strings and maybe (just maybe) offer something like this:
[tag("something").i("idk").c("idk2")(), ...other stuff]
or something... Idk if it would be worth it but it could represent some potential alternative solution for people who want to have a little of both words. Arbitrary function calling seems the most problematic to me...
Hi @nahuel, @Mateiadrielrafael - i've started working on this new package @thi.ng/hiccup-html which addresses and helps with some of these aspects, at least in the realm of HTML elements (but I still think a completely generic / general purpose approach is not ever gonna be feasible, too many edge cases in reality, not gonna fight it). The approach of that new package though, gives you full type checking and auto-complete for attributes (incl. arg types for event listeners), which should be a great help...
just released version 0.1.0 of @thi.ng/hiccup-html