Reputation: 1
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.
Upvotes: 0
Views: 247
Reputation: 1
Update after struggling with this some more:
The return type of defineComponent
needs to be of type DefineComponent
because it can be used as TSX value-based element -- https://www.typescriptlang.org/docs/handbook/jsx.html . And the above quoted tsx documentation specfies how the elements are typechecked. Namely, the element name must be within the ts scope and must be a constructor whose signature matches the attributes supplied to the tsx element. So, having the type of the result be compatible with the Options object (which the result actually is at runtime) will not work in that case.
Upvotes: 0