I am not too experienced with Typescript, however I am under the impression that if the declared types are correct, they should match the runtime structure of the objects they are describing. I am refactoring a Vue codebase (and migrating it to typescript) where the Vue component definition is modified after importing it from an SFC.
The original code expected the imported component definition to have certain structure (concretely to have ‘props’ field) which it did. However, after moving it ot typescript and enabling typechecking, the type of the imported component definition is DefineComponent — https://github.com/vuejs/core/blob/574c3e63bbb764c82fd7228eac979bb3e7fa731d/packages/runtime-core/src/apiDefineComponent.ts#L44 which has completely different structure and does not have the ‘props’ field.
My question is why is this discrepancy.
We can observe the behaviour in a limited environment by creating the vue 3 scaffold project — https://cli.vuejs.org/guide/creating-a-project.html and then modifying the main.ts to the following:
import { createApp, defineComponent } from 'vue'
const comp = defineComponent({props: ['msg'], render:()=>"HELLO WORLD"})
console.log(comp)
new comp()
createApp(comp).mount('#app')
This code compiles correctly, specificly, the comp
variable can be used as a constructor (the type declaration for defineComponent
says it is). However, at runtime, the code fails, because comp
points to
{
"props": ["msg"],
"render": () => () => "HELLO WORLD"
}
I am expecting the value of comp
at runtime to be compatible with the declared type but that is not the case.
This behaviour is the same even if the component is an imported SFC and not defined inline.
burzoopak is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.