Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/preferences/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

- TypeScript types added for accessing the `core/preferences` store by name

## 4.36.0 (2025-11-26)

## 4.35.0 (2025-11-12)
Expand Down
16 changes: 16 additions & 0 deletions packages/preferences/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,19 @@ export const store = createReduxStore<
} );

register( store );

type SubsequentArgsOfFunc< F > = F extends ( arg: any, ...args: infer R ) => any
? R
: never;
type CurriedSelectors = {
[ key in keyof typeof selectors ]: (
...args: SubsequentArgsOfFunc< ( typeof selectors )[ key ] >
) => ReturnType< ( typeof selectors )[ key ] >;
Comment on lines +32 to +38
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SubsequentArgsOfFunc type helper is reinventing functionality that already exists in '@wordpress/data'. The CurriedState type in packages/data/src/types.ts (lines 146-150) provides the same functionality for currying selectors by removing the first state argument.

Consider using the built-in CurriedState type or CurriedSelectorsOf type from '@wordpress/data' instead of creating a custom implementation to maintain consistency with the framework's type system.

Copilot uses AI. Check for mistakes.
};
declare module '@wordpress/data' {
function dispatch( key: typeof STORE_NAME ): typeof actions;
function select( key: typeof STORE_NAME ): CurriedSelectors;

function useDispatch( key: typeof STORE_NAME ): typeof actions;
function useSelect( key: typeof STORE_NAME ): CurriedSelectors;
}
Comment on lines +31 to +46
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This module augmentation pattern may not work as intended in TypeScript. When augmenting a module that exports functions using 'export function', adding 'declare function' overloads in the augmentation doesn't reliably create merged overloads - the behavior depends on the TypeScript version and module resolution settings.

The recommended approach for type-safe store access is to use the store descriptor object directly (the exported 'store' constant) rather than string names, as this is how the '@wordpress/data' types are designed to work. If string-based access with types is required, the '@wordpress/data' package would need to expose these functions through an interface or namespace that can be properly augmented.

You may want to verify this augmentation works correctly across different TypeScript configurations and versions before merging.

Suggested change
type SubsequentArgsOfFunc< F > = F extends ( arg: any, ...args: infer R ) => any
? R
: never;
type CurriedSelectors = {
[ key in keyof typeof selectors ]: (
...args: SubsequentArgsOfFunc< ( typeof selectors )[ key ] >
) => ReturnType< ( typeof selectors )[ key ] >;
};
declare module '@wordpress/data' {
function dispatch( key: typeof STORE_NAME ): typeof actions;
function select( key: typeof STORE_NAME ): CurriedSelectors;
function useDispatch( key: typeof STORE_NAME ): typeof actions;
function useSelect( key: typeof STORE_NAME ): CurriedSelectors;
}

Copilot uses AI. Check for mistakes.
Loading