Vite/Vue3 OptionAPI mixin typings for props and head function with defineComponent

125 Views Asked by At

I have a problem to type our custom plugins for a ts mixins in vue3.

We migrated our delivery from nuxt2/vue2 to vite/vue3. Having all our components written for OptionAPI, we have some mixins.

Typing them looks quite simple in the documentation, just wrap it in defineComponent(). To type our plugins we tried to pass an own type like defineComponent<DefaultPageProperties>().

That helps with the plugins and also give us some vue component typings. The defineComponent() method decides if it is a Composition or an OptionApi mixin and in some cases it decides it's an ComponentOptionsWithoutProps. Even if there are props! Is there a way to detect props and the head functions automatically without defining them again? Props work with just defineComponent() but we can't use our plugins in those mixins anymore.

The bare minimum of our mixin looks like the following and still won't detect that there are props:

videoPlayerMixin = defineComponent<DefaultPageProperties>({
    props: {
        videoData: {
            type: Object,
            default: () => null,
        },
    },
})

The Type looks like (just changed own types to any .. dont worry):

import { DefineComponent } from 'vue'
export type DefaultPageProperties = DefineComponent & {
    $mobileHeaderIsSet: boolean
    $route: any
}

Are we on the right track and how to type it properly to work with props and the vue2 head function. Or is there a different way to type our plugins and just use defineComponent() as it is?

The Error messages with the type given to defineComponent():

The expected type comes from property 'props' which is declared here on type 'ComponentOptionsWithoutProps<DefaultPageProperties, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, {}, string, ComponentPublicInstanceConstructor<...> & ... 5 more ... & {}>'

We also tried to define the props by our own but it do not change anything to the Error:

type Props = {
    type:
        | BooleanConstructor
        | ObjectConstructor
        | ArrayConstructor
        | StringConstructor
        | NumberConstructor
        | null;
    default?: boolean | object | any[] | string | number | null;
}
export type DefaultPageProperties = DefineComponent & {
    $mobileHeaderIsSet: boolean
    $route: RouteData
    props: Record<string, Props>
}

We tried to declare it, but may we need another utility class, because the mixins won't know about our plugins that way: (without the DefaultPageProperties) (like described here)

declare module '@vue/runtime-core' {
    interface ComponentCustomProperties {
        $mobileHeaderIsSet: boolean;
        $route: any;
    }
}
0

There are 0 best solutions below