I created a method that I want to be accessible on all my Vue instances, so I can use it in case of an error and display a specific error component. Similar to the functionality provided by vue-error-page. Since I am working with typescript, I now want to ensure that the component is called with the correct typed props, to receive compile time errors if there is any inconsistency in the passed props.
Currently, I have the following code in a shims.d.ts file:
import Vue, {VueConstructor} from 'vue'
declare module 'vue/types/vue' {
interface Vue {
$error (component:VueConstructor<Vue>, props:unknown) : void;
}
}
This allows me to call my plugin like this. The object passed matches the props definition of the ErrorPage component:
import Vue from "vue";
import ErrorPage from "./views/ErrorPage.vue";
export default Vue.extend({
mounted() {
this.$error(ErrorPage, { errorTitle: "Could not load the page" });
}
});
Although it works, I aim to receive a compile-time error when the props don't align with what the component expects.
To achieve this, I decided to modify the shims.d.ts as follows:
declare module 'vue/types/vue' {
interface Vue {
$error<Props> (component:ExtendedVue<Vue, unknown, unknown, unknown, Props>, props:Props) : void;
}
}
Now, I encounter compile-time errors when the props object doesn't match. However, I also face errors when I do not provide optional properties. Here's how my ErrorPage component looks like:
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."
}
}
});
If I omit passing errorDescription, I should not receive an error. That's my objective. I want to be able to perform the following actions:
// Should compile successfully.
this.$error(ErrorPage, {errorTitle: "Oops", errorDescription: "Something went wrong" });
// Should compile successfully but currently does not. Results in error message:
// 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 Question:
How can I make sure that my method call remains type-safe with props as an argument, while still allowing for optional properties to be omitted? I have the flexibility to modify both the shims.d.ts and the ErrorPage component.