【问题标题】:Vue: Typed props interface with optional propertiesVue:具有可选属性的类型化道具接口
【发布时间】:2020-05-10 07:13:07
【问题描述】:

我创建了一个我希望在所有 Vue 实例上都可用的方法,我可以在发生错误时调用它并呈现特定的错误组件。像vue-error-page 这样的东西。我正在使用打字稿,现在我想确保使用正确的类型化道具调用组件,如果传递的道具中有错字,则会出现编译时错误。

目前我在 shims.d.ts 文件中有这个:

import Vue, {VueConstructor} from 'vue'

declare module 'vue/types/vue' {
    interface Vue {
        $error (component:VueConstructor<Vue>, props:unknown) : void;
    }
}

这让我可以像这样调用我的插件。传入的对象与 ErrorPage 组件的 props 定义匹配:

import Vue from "vue";
import ErrorPage from "./views/ErrorPage.vue";
export default Vue.extend({
  mounted() {
    this.$error(ErrorPage, { errorTitle: "Could not load the page" });
  }
});

虽然这有效,但如果 props 与组件期望的不匹配,我想得到一个编译时错误。

所以我想我会像这样更改 shims.d.ts:

declare module 'vue/types/vue' {
    interface Vue {
        $error<Props> (component:ExtendedVue<Vue, unknown, unknown, unknown, Props>, props:Props) : void;
    }
}

现在,当 props 对象不匹配时,我会收到编译时错误。但是,当我不传入可选属性时,也会出现错误。我的 ErrorPage 组件如下所示:

import Vue from "vue";
export default Vue.extend({
  name: "Error",
  props: {
    errorTitle: {
      type: String,
      required: true,
      default: "Error"
    },
    errorDescription: {
      type: String,
      required: false,
      default:
        "Something went wrong."
    }
  }
});

如果我没有通过 errorDescription,我不应该得到错误。这就是我想要完成的。我希望能够做到以下几点:

// Should compile and does right now.
this.$error(ErrorPage, {errorTitle: "Oops", errorDescription: "Something went wrong" });

// Should compile and does not right now. Fails with error:
// Argument of type '{ errorTitle: string; }' is not assignable to parameter of type '{ errorTitle: string; errorDescription: string; }'.
// Property 'errorDescription' is missing in type '{ errorTitle: string; }' but required in type '{ errorTitle: string; errorDescription: string; }'."
this.$error(ErrorPage, {errorTitle: "Oops" });

TL;DR 问题:

如何使用 props 作为参数使我的方法调用类型安全,同时能够省略可选属性?我可以同时更改 shims.d.ts 和 ErrorPage 组件。

【问题讨论】:

    标签: typescript vue.js


    【解决方案1】:

    即使您将其标记为不需要,打字稿类型仍然是String,因此您需要在调用方法时传递它。

    你可以试试这个(我没有测试它是否有效)

    使用别名声明一个可以为空的类型

    type ErrorDescriptionType = String | undefined | null

    然后将其作为errorDescription 的类型传递

    errorDescription: {
      type: Object as () => ErrorDescriptionType,
    }
    

    【讨论】:

    • 这是个好建议。不幸的是,我仍然遇到同样的错误。
    猜你喜欢
    • 2023-04-10
    • 2021-04-14
    • 2019-12-06
    • 2020-05-04
    • 1970-01-01
    • 2016-10-05
    • 2013-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多