Description
Vue version
3.2.47
Link to minimal reproduction
Steps to reproduce
App fails at runtime even though TypeScript and Volar are happy with defineComponent Props type.
App.vue
<script lang="ts">
import Comp from './Comp.vue'
export default {
components: {
Comp,
}
}
</script>
<template>
<!-- Volar correctly shows an error here if someProp is not passed -->
<!-- (even without Comp specifying runtime props) -->
<Comp :some-prop="Hooray"/>
<!-- TypeScript and Volar are happy after passing someProp, but runtime fails -->
</template>
Comp.vue
<script lang="ts">
import { defineComponent } from 'vue'
// Specifying the Props type doesn't require a runtime props declaration
export default defineComponent<{ someProp: string }>({}) // No type error here
</script>
<template>
<!-- Volar types someProp as a string here, as I'd expect -->
<h1>someProp: {{ someProp }}</h1>
</template>
What is expected?
Initially from reading the Vue docs, I expected to see a type error about not specifying the runtime props in the object passed to defineComponent
along the lines of "Type undefined not assignable to (whatever my prop types were)".
BUT when I realized that TypeScript was happy AND that Volar was correctly seeing the prop type in the template AND that Volar was seeing the prop as required in the parent component's template...I started to think that this would "just work" even in runtime.
What is actually happening?
Sadly the app still failed at runtime with the error
Property "someProp" was accessed during render but is not defined on instance.
at <Compsome-prop=undefined>
at <Repl>
But then I thought...why does that need to fail? Ultimately I don't care about the runtime validation if TypeScript and Volar are already validating the props as I'm writing the code. Now runtime validation of component props feels like trying to do runtime validation of function params - we don't really need it.
System Info
System:
OS: macOS 12.6.3
CPU: (10) arm64 Apple M1 Pro
Memory: 204.77 MB / 32.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.14.0 - ~/.nvm/versions/node/v16.14.0/bin/node
npm: 8.3.1 - ~/.nvm/versions/node/v16.14.0/bin/npm
Browsers:
Chrome: 110.0.5481.177
Firefox: 101.0
Safari: 16.3
npmPackages:
vue: ^3.2.45 => 3.2.47
Any additional comments?
As a side note, part of my motivation for trying the generic Props type parameter in the first place is that I hate the idea of using JS prototypes just to accomplish all I really care about, which is type checking.
I would ALSO love if defineComponent's "Emits" generic type parameter could be second in the list of type parameters instead of way later...because if I'm able to specify both the props and the emits types right there in defineComponents
(and if I can opt out of the runtime validation for both), then 💯 🎉