WebReflection / uhtml

A micro HTML/SVG render

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Renderable type doesn't include valueOf?

pjeby opened this issue · comments

TypeScript doesn't seem to consider objects Renderable, whose valueOf() is a Renderable, even though from a glance at the source it appears render() would place such an object. I'm not sure if this is an issue with the types, or if you're actually not supposed to pass such objects (e.g. signals) to render()? I'd have guessed from the recent additon of signals support that signals are intended to be supported, i.e. something like:

export type SimpleRenderable = Hole | HTMLElement | SVGElement; 
export type Renderable = SimpleRenderable | { valueOf(): SimpleRenderable }; 

But maybe I'm overgeneralizing and in fact you're not supposed to do that. 😀

I've no idea what you are talking about ... do you have actual code that doesn't work or we're talking TypeScript only shenanigans? I don't use TS for this any dozen other reasons but I'm happy to make TS users happier if they can help me understanding what is it that TS complains about and how to fix it in TS ... the valueOf() is used a lot internally to trigger static fragments and when it comes to signals it uses .value or .valueOf instead, depending on the signal library you pick.

So, my real question I guess was "can the what argument to render() be any object with a .valueOf(), or must it be only one of the things listed as Renderable currently (i.e. a Hole or an Element)? " If it's only one of those things, then fine, I'll just call valueOf before passing it to render.

I expect I am confused in part because I sort of expected the argument to render() to be like a template value, where you can pass arrays of things and they can be pretty much whatever, such as things with a .valueOf(). But it appears that I would need to instead do something like:

render(parent, html`${thingWithAValueOfThatReturnsAnArrayOfElements}`);

rather than just:

render(parent, thingWithAValueOfThatReturnsAnArrayOfElements);

The latter gave me a type error from TypeScript, so I went to investigate and thought maybe the TypeScript hadn't been updated when signal support was added. In hindsight that appears to be an invalid assumption on my part, as I assumed a symmetry between render() and template interpolation that probably doesn't actually exist.

render accepts Hole which is a class already and interpolations can be primitives or Hole ... there is much more going on behind the scene due diffing and everything and the html guards it's going to be html and not svg, as example, otherwise how can I possibly know what are you rendering by a list of arrays?

in short, you must use the primitives this library provide: that is html and svg to render either types. What you put in those interpolations must be API compatible and the documentation should help you understand what's accepted in interpolations and what's not.

That's it. Closing as there's nothing to do here for me but feel free to ask more, if needed.

P.S. specially arrays, need to be converted as static fragments so you need to place a pin-comment to understand where the static fragment should be updated/replaced ... this module does a lot behind the scene, far away from being "just a template literal" on its what definition ... I hope this is clear now.

No problem; I just am unused to being able to sling fragments around without special handling -- render() looks at first glance a lot like redom's mount() (which requires an element rather than a fragment), so I was trying to apply a redom solution to a uhtml problem, so to speak. 😄