-
-
Notifications
You must be signed in to change notification settings - Fork 9k
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.37Any 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