How to Properly Register axios Globally in Vue & TypeScript Application

Viewed 2439

I've been fighting with Vue, TypeScript and Axios and I cannot arrive at what feels like a satisfactory solution.

Most guides will tell you to do this:

Main.ts

import axios from 'axios';

Vue.prototype.$http = axios;

And then use the $http. TypeScript doesn't like this:

Property '$http' does not exist on type CombinedVueInstance

How can I register axios globally and avoid any TypeScript errors?

Based on @GentlemanCrow answer below I created a file in my root directory called:

axios-plugin.d.ts

import _Vue from 'vue';
import Axios from 'axios';

export function AxiosPlugin<AxiosPlugOptions>(Vue: typeof _Vue, options?: AxiosPluginOptions): void {
    // do stuff with options
    Vue.prototype.$http = Axios;
}

export class AxiosPluginOptions {
    // add stuff
}

import { AxiosStatic } from 'axios';

declare module 'vue/types/vue' {
    interface Vue {
        $http: AxiosStatic;
    }
}

This produces the error:

(TS) An implementation cannot be declared in ambient contexts.

And on Vue.prototype.$http = Axios; the error is:

Statements are not allowed in ambient contexts.

Removing the export function AxiosPlugin function and attempting to execute a request errors with:

TypeError: "this.$http is undefined"

Where should the following code go?

export function AxiosPlugin<AxiosPlugOptions>(Vue: typeof _Vue, options?: AxiosPluginOptions): void {
    // do stuff with options
    Vue.prototype.$http = Axios;
}
1 Answers

I believe you have to register it as a typescript declaration file - so create a separate file called 'axios-plugin.d.ts' and put in:

import _Vue from 'vue';
import Axios from 'axios';

export function AxiosPlugin<AxiosPlugOptions>(Vue: typeof _Vue, options?: AxiosPluginOptions): void {
    // do stuff with options
    Vue.prototype.$http = Axios;
}

export class AxiosPluginOptions {
    // add stuff
}

import { AxiosStatic } from 'axios';

declare module 'vue/types/vue' {
    interface Vue {
        $http: AxiosStatic;
    }
}

then you should have access to Vue.$http where you need it.

Vue.prototype.$http = axios; would work in pure javascript but Typescript forces you to declare everything BUT you get that sweet, sweet type checking.

You can see some more general info on definition files here, along with an Axios example: How to augment the Vue class and keep typescript definition in sync

Related