打字稿扩展/修改现有接口-Vue Router Meta

时间:2019-06-05 15:54:04

标签: typescript vue.js vue-router

很抱歉,如果这个问题已经回答,但我似乎在任何地方都找不到答案。如果有一个好的答案,请有人链接。

我正在尝试扩展应用程序内node_module内的现有打字稿接口。 “扩展”是指覆盖使用的默认定义。当前已设置“ meta”,我想更改它而不是创建一个使用当前库中接口的新接口来使用。

我想尝试将此附加到this。$ router.currentRoute.meta的全局实例上,而不是每次使用它时都执行“ as TYPE”。

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

谢谢。

1 个答案:

答案 0 :(得分:0)

不确定您是否已经找到解决方案,但是如果有人偶然发现了这篇文章,这对我有用。

创建了一组Vue插件,并希望扩展Typescript的类型。

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

类型/ 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 }
}