I have a Vue 3 / TypeScript app that uses Pinia and Vue Concurrency.
And I have been playing around to see if I can use Vue Concurrency inside Pinia.
This is what I have in Pinia at the moment:
import { defineStore } from 'pinia';
import { User } from 'src/types';
import { useUpdateDocTask } from 'src/composables/database';
import { useTask } from 'vue-concurrency';
const updateDocTask = useUpdateDocTask();
export const useUserStore = defineStore('user', {
state: () => {
return {
user: {} as User,
};
},
actions: {
setFirstNameTask() {
return useTask(function* (signal, firstName: string) {
this.user.firstName = firstName; // ERROR HERE
yield updateDocTask.perform('users', this.user.uid, { // ERROR HERE
firstName,
});
});
},
});
But I am getting these TypeScript and Eslint errors on all instances of this
:
this' implicitly has type 'any' because it does not have a type annotation. ts(2683)
user.ts(38, 22): An outer value of 'this' is shadowed by this container.
Unsafe member access .user on an `any` value.eslint @typescript-eslint/no-unsafe-member-access
Is it possible to overcome these errors?
How could this be done correctly?
CodePudding user response:
This is a special case of this common problem, the problem is that generator function doesn't have arrow counterpart, and needs to be bound to correct this
, and also typed correctly.
Considering that useTask
doesn't provide specific functionality to bind callback context and infer thisArg
type, it will work as:
type This = typeof this;
return useTask(function* (this: This, signal, firstName: string) {
this.user...
...
}.bind(this));
Or with old-fashioned self = this
recipe:
const state = this;
return useTask(function* (signal, firstName: string) {
state.user...
...
});