Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugins: Expose DefineStoreOptionsBase in PiniaCustomProperties #1247

Open
b-strauss opened this issue Apr 22, 2022 · 4 comments
Open

Plugins: Expose DefineStoreOptionsBase in PiniaCustomProperties #1247

b-strauss opened this issue Apr 22, 2022 · 4 comments
Labels
feature request typescript This issue is related to typings

Comments

@b-strauss
Copy link

What problem is this solving

I wrote a plugin to solve #625. This is basically working, but the types of the stores defined in the new stores option in DefineStoreOptionsBase are not accessible inside PiniaCustomProperties.

import type {PiniaPluginContext, Store, StoreDefinition} from 'pinia';

declare module 'pinia' {
  export interface DefineStoreOptionsBase<S, Store> {
    stores?: Record<string, StoreDefinition>;
  }

  export interface PiniaCustomProperties<Id, S, G, A> {
    readonly stores: Readonly<Record<string, Store>>;
  }
}

export function piniaPluginStores (context: PiniaPluginContext) {
  return {
    get stores () {
      return Object.freeze(
        Object.entries(context.options.stores ?? {})
          .reduce<Record<string, Store>>((accumulator, [name, definition]) => {
            accumulator[name] = definition();
            return accumulator;
          }, {}),
      );
    },
  };
}

Proposed solution

If the store options would be accessible inside PiniaCustomProperties, the actual types of the concrete stores could be accessed with this.stores.

Describe alternatives you've considered

No response

@posva
Copy link
Member

posva commented Apr 22, 2022

I don't understand what change you are suggesting. Can you open a PR with your proposal instead?

@b-strauss
Copy link
Author

b-strauss commented Apr 22, 2022

I currently don't have time, but basically when you use the above plugin, there is no way to get to the actual types of the stores that have been defined in the stores option, because the DefineStoreOptionsBase are unknown to PiniaCustomProperties, unless I misunderstand how the current plugin types work.

const useUserStore = defineStore('user', {
  state: () => ({
    name: 'Max Power',
  }),
  getters: {
    getName (state) {
      return state.name;
    },
  },
});

const useTestStore = defineStore('test', {
  stores: {
    // userStore type is known here
    userStore: useUserStore,
  },
  actions: {
    log () {
      // userStore type is unknown here 
      console.log(this.stores.userStore.getName);
    },
  },
});

It would be great if the types in this.stores could be inferred automatically by whats given to the stores option.

@posva posva added the typescript This issue is related to typings label Apr 22, 2022
@posva
Copy link
Member

posva commented Apr 22, 2022

I see. I don't think this is actually feasible even with a small breaking change. Let's give it some time so people can share their ideas.

@Ilanaya
Copy link

Ilanaya commented Nov 14, 2023

@posva I have a case which justifies adding DefineStoreOptionsBase type to PiniaCustomProperties.

I'm using options stores like this:

defineStore('name', {
    state: () => ({
      controllers: initAbortController(
        'update',
        'updateList',
      ),
    }),
    actions: {
       update() {},
       updateList(){}
      }
    }

Where initAbortController takes actions names as argument. This is inconvenient as

  1. I have zero suggestions for initAbortController() argument values
  2. This logic boilerplates in almost every store

If I could access DefineStoreOptionsBase I would

  • move the initAbortController logic to plugin
  • register actions I want to abort in the stores ( i.e. create custom store option which would consist of the desired list of actions names).

Like this:

defineStore('name', {
    actions: {
       update() {},
       updateList(){}
      }
    },
    controllers: ['update', 'updateList']

Currently I can't do this because of the related type issue.

Typings for this would look like this if PiniaCustomProperties would have access to DefineStoreOptionsBase

declare module 'pinia' {
  export interface DefineStoreOptionsBase<S, Store> {
    controllers?: Array<keyof StoreActions<Store>;
  }

  export interface PiniaCustomProperties {
  //                             ↓ No access to store options here
      controllers?: DefineStoreOptionsBase['controllers']
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request typescript This issue is related to typings
Projects
None yet
Development

No branches or pull requests

3 participants