Subscribe on changes!

defineProps doesn't support typing props with "Extract", a native TypeScript's feature.

avatar
Dec 13th 2022

Vue version

3.2.44

Link to minimal reproduction

https://sfc.vuejs.org/#eNqVUs1u2zAMfhVCF29AIt8910DaDeiAASuwwy66uDbtKLUpQWKSDZnffZTdom566sUWSX0/+qSL2nmvT0dUhSoZRz/UjJUhgPLe3rnRO0Ji6GyIvB2QGcONUTujIGLjqH3t3RpVlfkKJCxlvqKUMjbBehYoHz0MNfWC4yhAQ1ZQgeGNaHAjZHrNmZxmiXdhEpzaqAW6HWuvD9GRnOSSDmCeB8JfwNxJPSFItVF7Zh+LPI9dk1gPUbvQ57LS4UhsR9QYx+1jcOeIQYiNShSToUkkryxdhWe4bO2purdlnv5zmmlxucw5/pgjm6Z30yXS6/EHQuS/HmHBww1kuwz+QXY7f++yLwndYmcJH4LzsZRMDK8cFS/QPIffLjxFuXZCnQyunRXw7Q+HuuFyqTdJokqgrw4jkGM4C1rDQ7DEEc51IEs9WAIhiW7AAr7TqR5sC16MFDDbbvbYPEFX2wFb6FyYZ3JPa2mjtIh7bFj2/Hw8yGIDvQj+YtHq4Wx5D8J8RAHKgxTvU/Xp8+rBqOk/mqwIHQ==

Steps to reproduce

  1. Create new Vue 3 project with npm create vue@3 command.
  2. 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>
  1. 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>
  1. Start project with npm run dev command.
  2. 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.

avatar
Jan 23rd 2023

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>