feat(types): expose store options to plugins via PiniaCustomOptionsProperties - #3174
feat(types): expose store options to plugins via PiniaCustomOptionsProperties#3174haoku123 wants to merge 1 commit into
Conversation
…operties Plugins adding properties through PiniaCustomProperties cannot type them from the options passed to defineStore(), because the options type is never threaded into the store type. Add a PiniaCustomOptionsProperties<O> interface intersected into Store, carrying the resolved store options (including custom options declared on DefineStoreOptionsBase through module augmentation), and pass it through defineStore/StoreDefinition/SetupStoreDefinition. mapStores keeps the options type through _StoreObject so mapped stores preserve the plugin properties. Closes vuejs#1247
✅ Deploy Preview for pinia-playground ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for pinia-official canceled.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Problem
Closes #1247
Plugins can add custom options through
DefineStoreOptionsBase(module augmentation) and read them in the plugin callback viacontext.options, but there is no way to type properties returned by the plugin from those options.PiniaCustomPropertiesonly receivesId,S,G,A— the options type is never threaded into the store type, sothis.stores(or any other option-derived property) can only be typed with the widestStore/Recordtypes.Solution
Add a dedicated
PiniaCustomOptionsProperties<O>interface intersected intoStore, mirroring the existingPiniaCustomPropertiespattern:The resolved options of each store flow into
Owithout any change to user-facing signatures:defineStorereturnsStoreDefinition<Id, S, G, A, DefineStoreOptions<Id, S, G, A>>(and the setup overload passesDefineSetupStoreOptions),StoreDefinitionandSetupStoreDefinitionforwardO, andStoreintersectsPiniaCustomOptionsProperties<O>.Odefaults to_Empty, so existing code that writesStore<Id, S, G, A>orStoreGenericis unaffected.The plugin from the issue then works with full typing:
mapStoresis updated so_StoreObjectkeeps the options type through itsStoreDefinitioninference (previously the 4-parameterinferwould have silently droppedO, losing the plugin properties on mapped stores).Tests
Added
test-dts/storeOptions.test-d.tsrecreating the #1247 plugin scenario: customstores/markeroptions declared through augmentation are resolved on the store instance, with and without the custom options. Full suite passes:pnpm run test:types,pnpm run test:dts, andpnpm run test:vitest run(260 tests).Notes
This is type-only: no runtime changes. The earlier attempt at #3042 (closed) added a runtime
_optionsfield; this approach keeps everything at the type level, matching howPiniaCustomPropertiesalready works.