Note on Typing Dynamic Vue Components with Typescript
Say you want to render a different component based on some condition
dynamicComponent(foo: Foo) {
return foo.bar === 'baz' ? FunComponent : SeriousComponent
}
Which you could then use in your vue template like any other computed property, using the <component is:>
style
<component :is="dynamicComponent(foo) />
This would render either the FunComponent or SeriousComponent based on a condition / property on object passed to the computed property that returns them.
How to type this was a mystery to me until recently when I found out that Vue
is not the only exported member of /node_modules/vue
import Vue, { Component, AsyncComponent } from 'vue'
The computed property's return value can be types as:
dynamicComponent():
| Component<any, any, any, any>
| AsyncComponent<any, any, any, any>
Looking into the src from the import for component yields:
// we don't support infer props in async component
// N.B. ComponentOptions<V> is contravariant, the default generic should be bottom type
export type Component<Data=DefaultData<never>, Methods=DefaultMethods<never>, Computed=DefaultComputed, Props=DefaultProps> =
| typeof Vue
| FunctionalComponentOptions<Props>
| ComponentOptions<never, Data, Methods, Computed, Props>
For AsyncComponentType:
export type AsyncComponent<Data=DefaultData<never>, Methods=DefaultMethods<never>, Computed=DefaultComputed, Props=DefaultProps>
= AsyncComponentPromise<Data, Methods, Computed, Props>
| AsyncComponentFactory<Data, Methods, Computed, Props>
Pretty cool. You can see more exported types at node_modules/vue/types/options.d.ts