`defineProps` seems to ignore props marked as optional and requires them anyway when using TypeScript tooling
Version
3.2.31
Reproduction link
Steps to reproduce
Create a new project using the following command:
$ npm create vite@latest
$ npm install
Use Vue and TypeScript.
Then, create a new component CustomComponent.vue
(the name doesn't really matter) with the following content:
<script setup lang="ts">
const $props = defineProps({
text: {
type: String,
required: true,
},
optional: {
type: String,
required: false,
default: 'this is not required'
},
});
</script>
<template>
{{ $props.text }}
</template>
Now, when importing the component into another component, omitting the non-required prop will cause a type error.
Notice that this doesn't happen when using the Options API, only when using script-setup
:
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'CustomComponent',
props: {
text: {
type: String,
required: true,
},
optional: {
type: String,
required: false,
default: 'this is not required'
},
},
});
</script>
<template>
{{ text }}
</template>
What is expected?
The TypeScript tooling should recognize that the optional
prop is not required.
What is actually happening?
The TypeScript tooling seems to think that the optional
prop is required.
This doesn't seem to be an issue when defining props with the interface syntax:
<script setup lang="ts">
const $props = defineProps<{
text: string,
optional?: string,
}>();
</script>
<template>
{{ $props.text }}
</template>
However, when using the withDefaults
compiler macro with the interface syntax, the exposed interface once again seems to ignore some values are marked as optional:
<script setup lang="ts">
const $props = withDefaults(defineProps<{
text: string,
optional?: string,
}>(), {
optional: 'this is optional',
});
</script>
<template>
{{ $props.text }}
</template>
I should point out that the compilation process itself works fine. It just seems to be the tooling that's failing randomly.
Hm, this seems to be related to the variable name you chose. $props
is part of the Vue component API, and it seems it's somehow confusing Volar. Changing it to const props
fixed the issues, changing it back made them reappear.
this issue should likely be moved to the Volar repo: https://github.com/johnsoncodehk/volar