Vue's ref
function can create a typed Ref
object, and the value type can optionally contain undefined
. Is there a way to set types so that assigning a Ref<string>
to Ref<string | undefined>
is prevented by Typescript?
Here I create a Ref<string>
and try to assign undefined
, which (as expected) causes an error:
const s1 = ref('hello') // typed as Ref<string>
s1.value = undefined // causes a TS error as expected: "Type 'undefined' is not assignable to type 'string'"
However, I can assign this ref to another ref supporting undefined
, which erases the type check:
const s2: Ref<string | undefined> = s1 // IMO unsafe assignment -- how to make this illegal?
s2.value = undefined
const s: string = s1.value // TS thinks that the value is still a string, but actually it's undefined
I encountered this problem while writing a function which should (among other things) unset the value of a ref. I'd like to have TS support for only passing refs with valid types:
function unsetRef<T>(r: Ref<T | undefined>) {
r.value = undefined
}
unsetRef(s1) // expected to be ok
unsetRef(s2) // expected to fail, but causes no TS error
You can make it generic and check if the ref's type includes undefined
, and if it doesn't include undefined
, then disallow the call by changing the type to never
:
function unsetRef<T extends Ref<unknown>>(r: undefined extends T["value"] ? T : never) {
const s1 = ref('hello');
const s2 = ref<string | undefined>("hello")
unsetRef(s1); // error
unsetRef(s2); // okay