I am migrating my Vue.js
components to TypeScript. Following the guide, I tried to use Vue.extend()
for my component. My component is:
import Vue from 'vue';
const Component = Vue.extend({
// type inference enabled
created() {
// `y` is non-reactive property
this.y = 20; // TYPESCRIPT THROWS ERROR
}
data() {
return {
// x is reactive property
x: 10
};
}
});
In above example, I have property x
which is reactive and y
as non-reactive property. However, I just cannot get type inference working for property y
due the way augmentation works in TypeScript.
I cannot use simple object export for defining my component as it starts throwing a type error for both y
and x
.
For, now I am sticking to keeping this file as JS or move my code vue-class-component
which enable me to handle this. However, I am reluctant to move to vue-class-component
as it is a code at a library level.
Any solution to how I can make TypeScript
happy?
You should also be familiar with Vue, vue-loader, and webpack. Vue 2 already has good support for TypeScript, and the recently published Vue 2.7 backported a lot of useful features from Vue 3, like composition API, <script setup> , and defineComponent , further improving the developer experience of TypeScript in Vue.
defineComponent({ setup: function , name: 'some name' }); As you see, all these cases are responsible for different scenarios, yet the return type is always the same: a defineComponent interface with all the types you need to apply for the props, data and the other settings that are needed for the component.
The Reactive Method #observable() in Vue 2.6, can be useful when we're trying to create an object all of whose properties are reactive (such as the data object in the Options API). Under the hood, the data object in the Options API uses this method to make all of the properties in it reactive.
A simplest solution would be something like this:
data() {
return {
// x is reactive property
x: 10
} as any as { x: number; y: number };
}
however that requires you to explicitly define all properties of data
.
Alternatively, you can do it with the following helper:
function withNonReactive<TData>(data: TData) {
return <TNonReactive>() => data as TData & TNonReactive;
}
Like this:
data() {
return withNonReactive({
// x is reactive property
x: 10
})<{
// non-reactive properties go here
y: number
}>();
}
One way to get rid of TypeScript errors this is by defining the following property:
data() {
return {
nonReactive: {} as any
}
}
and then just add your non-reactive properties to this object in created().
created() {
this.nonReactive.foo = {}
}
Another method I haven't really explored would be to create a typescript shim file for your component.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With