Peter I
Peter I

Reputation: 942

Typescript extending / modifying existing interface - Vue Router meta

Sorry if this question has been answered but i cant seem to find the answer anywhere. If there is a good answer please can someone link it.

Im trying to extend an existing typescript interface thats within a node_module within my application. By 'extend' i mean overwrite the default definition used. 'meta' is currently set and i want to change it rather than create a new interface to use that uses the interface from the current lib.

I would like to try and attach this to the global instance of this.$router.currentRoute.meta rather than doing a 'as TYPE' every time i use it.

router.ts

export interface Meta {
    Auth: boolean,
    displayName: string | null
}

shims-vue.d.ts

import {Meta} from '@/router'

declare module "vue/types/vue" {
  interface Vue{
    $router: {
      currentRoute: {
        meta: Meta // This should be set to my new Meta interface rather than the default meta?: any type within vue-router/types/router.d.ts
      }
    }
  }
}

page.vue

const name = this.$router.currentRoute.meta.displayName // type: any

Thanks all.

Upvotes: 1

Views: 4252

Answers (1)

Jeremy Travis
Jeremy Travis

Reputation: 133

Not sure if you already found a solution, but this worked for me, so I share this if anyone looking for a solution stumbles upon this post.

I created a set of Vue plugins and wanted to extend TypeScript's typings.

tsconfig.json

{
  "compilerOptions": {
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": true,
    "sourceMap": true,
    "target": "es5",
    "module": "es2015",
    "outDir": "lib",
    "baseUrl": ".",
    "paths": {
      "vue": [ "node_modules/vue/types/index" ],
      "vue-router": [ "node_modules/vue-router/types/index" ],
      "vuex": [ "node_modules/vuex/types/index" ],
      "axios": [ "node_modules/axios/index" ]
    }
  },
    "compileOnSave": false,
    "exclude": [
      //"node_modules",
      "wwwroot"
    ]
  }

typings / vue-extension.d.ts

/**
 * Augment the typings of Vue.js
 */

import Vue from 'vue'
import { AxiosStatic } from "axios"

declare module '../../../node_modules/vue/types/vue' {
    interface Vue {

        /**Axios HTTP client */
        $http: AxiosStatic;

        /**
         * Check if user belongs to an application role
         * @param role single role or array of roles
         * @returns True/False
        */
        $UserInRole(role: string | string[]): boolean;

        /**Executes box widgets (Collapse/Remove) */
        $boxWidget(): void;
    }
}

user-profile.ts

import Avatar from "../../../node_modules/vue-avatar/index";
import Vue, { ComponentOptions } from "vue";

export default {
    name: "user-profile",
    components: {
        Avatar
    },
    template: `<div> <avatar round :name="Fullname"></avatar> </div>`,
    data() {
        return {
            user: { "Title": "", "Bio": "" } as VueComp["user"]
        }
    },
    computed: {
        Fullname() {
            if (this.$store.state.profile.user.Fullname != undefined) {
                this.user.Title = this.$store.state.profile.info.Title;
                this.user.Bio = this.$store.state.profile.info.Bio;

                return this.$store.state.profile.user.Fullname;
            }
            return "";
        }
    },
    methods: {
        Save() {
            // Both $http and component's data extended from 'VueComp'
            let vm = this as VueComp;

            vm.$http.post("api/account/aboutme", vm.user)
                .then(() => {

                    let info = {
                        Title: vm.user.Title,
                        Bio: vm.user.Bio
                    };

                    //write back to store
                    vm.$store.commit("profile/Info", info);
                });
        }
    },
    mounted() {
        // $boxWidget extended from 'vue-extension.d.ts'
        let vm = this as Vue;
        vm.$boxWidget();
    }
} as ComponentOptions<any>


interface VueComp extends Vue {
    user: { Title?: string, Bio?: string }
}

Upvotes: 1

Related Questions