defineProps doesn't support typing props with "Extract", a native TypeScript's feature.
Vue version
3.2.44
Link to minimal reproduction
Steps to reproduce
- Create new Vue 3 project with
npm create vue@3
command. - Create a component
\src\components\HiComponent.vue
with the following code:
<template>
<div>Hi</div>
<div>{{firstLetter}}</div>
<div>{{secondLetter}}</div>
</template>
<script setup lang="ts">
type Letter = 'A' | 'B' | 'C';
defineProps<{
firstLetter: Letter // Works fine.
secondLetter: Extract<Letter, 'B'> // Does not work. Prints warning in console: Invalid prop: type check failed for prop "secondLetter". Expected Object, got String with value "B".
}>();
</script>
- Replace code in
\src\App.vue
file with the following code:
<template>
<HiComponent first-letter="A" second-letter="B"/>
</template>
<script setup lang="ts">
import HiComponent from './components/HiComponent.vue'
</script>
- Start project with
npm run dev
command. - Go to app's address (the default is
http://localhost:5173/
).
What is expected?
App runs without any warnings.
What is actually happening?
The following warning appears in console:
[Vue warn]: Invalid prop: type check failed for prop "secondLetter". Expected Object, got String with value "B".
at <HiComponent first-letter="A" second-letter="B" >
at <App>
System Info
System:
OS: Windows 10 10.0.22621
CPU: (16) x64 AMD Ryzen 7 5800H with Radeon Graphics
Memory: 11.73 GB / 27.86 GB
Binaries:
Node: 18.12.1 - C:\Program Files\nodejs\node.EXE
npm: 8.19.2 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: Spartan (44.22621.900.0), Chromium (108.0.1462.46)
Internet Explorer: 11.0.22621.1
npmPackages:
vue: ^3.2.45 => 3.2.45
Any additional comments?
TypeScript's Extract
suppose to return a new type, which is a subset of type passed to Extract as the first generic parameter. It feels like for some reason defineProps doesn't treat it correctly.
I just ran into this one today. Same error when extracting union members as a type outside of defineProps.
<script setup lang="ts">
type Letter = 'A' | 'B' | 'C';
type OnlyB = Extract<Letter, 'B'>;
defineProps<{
firstLetter: Letter // Works fine.
secondLetter: OnlyB // Does not work. Prints warning in console: Invalid prop: type check failed for prop "secondLetter". Expected Object, got String with value "B".
}>();
</script>