toRefs type is wrong when using defineProps with optional boolean props
Version
3.2.26
Reproduction link
Steps to reproduce
import { toRefs } from 'vue'
const props = defineProps<{
isLive?: boolean
}>()
const { isLive } = toRefs(props)
What is expected?
According to fix(runtime-core): ensure declare prop keys are always present type of isLive
should be:
Ref<boolean>
What is actually happening?
The type of isLive
actually is:
Ref<boolean | undefined> | undefined
isLive
couldn't be undefined in no case
In this test case if the props type is Boolean, absent should cast to false.
Interesting, I tend to think this is a bug, since other primitive type's default value is undefined
.
Interesting, I tend to think this is a bug, since other primitive type's default value is
undefined
.
If it's a bug,it's easy to fix,change the handling of this situation
// boolean casting
if (opt[BooleanFlags.shouldCast]) {
if (isAbsent && !hasDefault) {
value = false
} else if (
opt[BooleanFlags.shouldCastTrue] &&
(value === '' || value === hyphenate(key))
) {
value = true
}
}
to
// boolean casting
if (opt[BooleanFlags.shouldCast]) {
if (isAbsent && !hasDefault) {
value = undefined
} else if (
opt[BooleanFlags.shouldCastTrue] &&
(value === '' || value === hyphenate(key))
) {
value = true
}
}
but in this test case if the props type is Boolean, absent should cast to false.
@liulinboyi
If is a not a bug, why we need this behaviour, what is the motivation of this design? It is kind of odd and inconsistent to other types. IMO, absent value should always be undefined
.
I noticed that only boolean props will do the casting, other types will just remain undefined
(e.g. number, string).
@StephenChips I think there are two different moments: Ref<boolean | undefined>
and Ref<> | undefined
. Seems like the second has no sense (because keys are always present in props). The first case may be consistent behavior.
Even when using withDefaults setting the prop to undefined, the type becomes Ref<boolean>
but should be Ref<boolean | undefined>
Is there any workaround to use watchers on props without using toRefs ?