Description
Vue version
3.2.37
Link to minimal reproduction
Steps to reproduce
See reproduction link for full example.
I declare a property which allows undefined
:
const props = defineProps<{
modelValue: number | undefined
}>();
and actually pass undefined
:
<template>
<TheComponent v-model="value" />
</template>
<script setup lang="ts">
const value = ref<number | undefined>(undefined);
</script>
What is expected?
Vue doesn't emit runtime errors for explicitly allowed and used undefined
properties.
What is actually happening?
I get the following Vue runtime error in dev
mode
[Vue warn]: Invalid prop: type check failed for prop "modelValue". Expected Number | Null, got Undefined
This is because the SFC compiler emits the following property declaration. Note how null
was used instead of undefined
:
props: {
modelValue: { type: [Number, null], required: true }
},
If I modify the generated code and runtime like below (see <<<
and >>>
), to allow undefined
, it seems to work correctly. But I don't understand if there are other reasons for not allowing undefined
to be a required
property value:
// Component
props: {
modelValue: { type: [Number, undefined], required: true }
},
// Vue Runtime
function getType(ctor) {
const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
// <<<<<<<< added `undefined` support >>>>>>>>>>
return match ? match[1] : ctor === null ? "null" : ctor === undefined ? "undefined" : "";
}
function assertType(value, type) {
let valid;
const expectedType = getType(type);
if (isSimpleType(expectedType)) {
const t = typeof value;
valid = t === expectedType.toLowerCase();
if (!valid && t === "object") {
valid = value instanceof type;
}
} else if (expectedType === "Object") {
valid = isObject(value);
} else if (expectedType === "Array") {
valid = isArray$1(value);
} else if (expectedType === "null") {
valid = value === null;
// <<<<<<<< added `undefined` support >>>>>>>>>>
} else if (expectedType === "undefined") {
valid = value === undefined;
} else {
valid = value instanceof type;
}
return {
valid,
expectedType
};
}
System Info
System:
OS: Windows
Binaries:
Node: 18.7.0
npm: 8.15.0
npmPackages:
vue: ^3.2.37 => 3.2.37
Any additional comments?
I'm using undefined
when a value is not set by the user, for example empty number <input>
or unselected <select>
, as I understood to be current recommended practices:
Use undefined. Do not use null.
https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#null-and-undefined