How are you supposed to satisfy refs when not forwarding to a pure DOM node?

function Example() {
let controller: { open(): void } | undefined
return <>
<button onClick={() => controller?.open()}>Open</button>
<Controllable ref={controller} />
</>;
}

function Controllable(props: { ref: Ref<{ open(): void } | undefined> }) {
let dialog: HTMLDialogElement | undefined;
function open() {
// do some stuff
dialog?.showModal();
}
// How do I satisfy props.ref here properly? Or is this the way
// and is there a way to eliminate the `| undefined` in the type of the ref?
createRenderEffect(() => {
typeof props.ref === "function" ? props.ref({ open }) : console.log("no ref")
});
return <dialog ref={dialog}>Hello</dialog>;
}
function Example() {
let controller: { open(): void } | undefined
return <>
<button onClick={() => controller?.open()}>Open</button>
<Controllable ref={controller} />
</>;
}

function Controllable(props: { ref: Ref<{ open(): void } | undefined> }) {
let dialog: HTMLDialogElement | undefined;
function open() {
// do some stuff
dialog?.showModal();
}
// How do I satisfy props.ref here properly? Or is this the way
// and is there a way to eliminate the `| undefined` in the type of the ref?
createRenderEffect(() => {
typeof props.ref === "function" ? props.ref({ open }) : console.log("no ref")
});
return <dialog ref={dialog}>Hello</dialog>;
}
https://playground.solidjs.com/anonymous/17acd607-9d8f-4dd8-b098-5cf0b5c9fb07
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
3 Replies
foolswisdom
foolswisdom2mo ago
The ref prop received will be a function, even if the type passed to the ref prop is a variable (the compiler will simply create a function that takes a value and assigns to that variable). The Ref type allows for both, because it's defined in terms of the type that can be passed. If you don't like that, you should use a different type. The reason the type includes undefined is because you explicitly added undefined to the type generic passed to Ref, so of course TS says it's possibly undefined The compiler behavior applies to any prop named ref, iirc
webstrand
webstrandOP2mo ago
yep, I have to add that |undefined or I can't pass ref={controller} since typescript doesn't understand "write-only" properties there's no utility which does this? I have to do it all manually (or write my own utility)?
foolswisdom
foolswisdom2mo ago
I expect there's nothing built in. The types are often written with elements in mind, reusing them for components may not be feasible. In some cases it makes sense to adjust the existing types (make a PR), sometimes not
Want results from more Discord servers?
Add your server