InstanceType doesn't see exposed properties for components with `setup` returning render function
Vue version
3.3.4
Link to minimal reproduction
Steps to reproduce
Create a component with options API.
In setup
call an expose
and return a render function
<script lang="ts">
import { defineComponent, h } from 'vue'
export default defineComponent({
setup(_, { expose }) {
expose({
test: (a: string) => Promise.resolve(a)
})
return () => h('div')
}
})
</script>
Import it in another component and take its type via InstanceType
<script setup lang="ts">
import { ref } from 'vue';
import Comp from './Comp.vue'
const comp = ref<InstanceType<typeof Comp>>()
comp.value.test
</script>
What is expected?
Exposed properties are present in interface
What is actually happening?
Exposed properties are not present in interface
System Info
No response
Any additional comments?
No response
This is a limitation in typescript. These exposed variables cannot be known in type-level since they are bound to your runtime code
Yes, const comp = ref<InstanceType<typeof Comp>>()
is only responsible for type safety and can ensure that the type is correct when you write code. Vue will not generate its object based on this type during the compilation phase and pass it to the ref function to define a reactive
object.
@baiwusanyu-c Why Vue will not generate its object based on this type during the compilation phase
?
Why it's not planned?
Do you plan to deprecate render-functions?
@avinean No, he means: typescript cannot infer types from your runtime usage.
For example:
// We call this function to expose some thing
declare function expose<T>(exposed: T): void;
expose({ xxx: 1 }) // But we can't know we exposed a variable called `xxx` in type level. Thus we are unable to add it to the component instance's type.
What you said makes sense and clear for me. But I'm talking not about inferring types but about generating types. I mean watch components during development and dynamically generate types.