1

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.

4
  • 1
    Possible duplicate of Extending typescript interface Commented Jun 5, 2019 at 15:57
  • Search for "extend typescript interface" and you will find how to extend an interface. Commented Jun 5, 2019 at 15:57
  • No this is not not what im looking for. I think i have thrown you off by using the word 'extend' im looking to replace / override it within my application context. At the moment 'meta' is set to meta?: any. I want to change that any to be an interface so that when ever i refer to meta in my application it will be typed. Commented Jun 6, 2019 at 21:37
  • Does this answer your question? How to declare TypeScript type interface for custom meta fields in Vue Router v4? Commented Apr 5, 2022 at 10:21

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.