1

I have a Vue3 plugin in js, like that:

const myPlugin = {
    install(Vue, config) {
           // do something
    }
export default myPlugin;

It is in index.js, and will be invoked by app.use. For TS projects I need to create a type declaration. I found vue/types/plugin in the vue package with an interface for the object and a type for the install method. However I have no clue how to apply this to my plugin. What needsto be inside the d.ts file so the typescript compiler knows that myPlugin is supposed to be of type PluginObject?

Stiegi
  • 1,074
  • 11
  • 22
  • 1
    Does this answer your question? [Question about Vue 3 + TypeScript and Augmenting-Types-for-Use-with-Plugins](https://stackoverflow.com/questions/64118679/question-about-vue-3-typescript-and-augmenting-types-for-use-with-plugins) – ethan_you Feb 15 '21 at 06:10
  • In parts yes, but it lacks the information on how to augment plugin options. Image that hello Plugin there had a config object like the one in my simple example above, how do I augment that config object? – Stiegi Jun 15 '21 at 09:43

1 Answers1

2

As of Vue 3.1.1, App.use() allows the options argument to be any, which seems to prevent augmenting its type declaration. That is, this module augmentation does not override the original App.use() (perhaps because any supercedes MyPluginOptions):

declare module '@vue/runtime-core' {
  interface App {
    use(plugin: MyPlugin, ...options: MyPluginOptions[]): this;
  }
}

It seems the only current workaround is to edit node_modules/@vue/runtime-core/dist/runtime-core.d.ts directly, adding a generic to Plugin_2 and PluginInstallFunction to enable typing the options argument:

declare type Plugin_2<Option = any> = PluginInstallFunction<Option> & {
    install?: PluginInstallFunction<Option>;
} | {
    install: PluginInstallFunction<Option>;
};
export { Plugin_2 as Plugin }

declare type PluginInstallFunction<Option> = (app: App, ...options: Option[]) => any;

And then replacing the current App.use() with:

export declare interface App<HostElement = any> {
    use<Option>(plugin: Plugin_2<Option>, ...options: Option[]): this;
}

demo

I also submitted a PR to vue-next. If it gets merged, you wouldn't need module augmentation, as the options type would be automatically inferred.

tony19
  • 125,647
  • 18
  • 229
  • 307