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 typeexport 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