0

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?

TinyTiger
  • 1,801
  • 7
  • 47
  • 92

1 Answers1

2

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...
    ...
  });
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • Thanks for this, but unfortunatley both solutions have a console error `ReferenceError: Cannot access 'useUserStore' before initialization`. – TinyTiger Mar 07 '22 at 09:40
  • 1
    @TinyTiger You don't have any `useUserStore` anywhere in the code shown in the question. So the error you are mentioning is not in any way related to this question/answer and should not be used as an excuse to not accept this as an answer (because it **is** correct answer) – Michal Levý Mar 07 '22 at 13:29
  • @TinyTiger The error means that there's `useUserStore()` above useUserStore declaration, and this needs to be avoided. As it was said, this isn't shown in the question and is a different problem that the solution isn't supposed to affect. – Estus Flask Mar 07 '22 at 13:54
  • Ok thanks for explaining. Have accepted the answer and will try to debug this other problem separately. – TinyTiger Mar 07 '22 at 22:47