From fda218d53036922ea1826f65aaff0d240e5e3208 Mon Sep 17 00:00:00 2001 From: John Hooks Date: Fri, 10 May 2024 21:15:32 -0700 Subject: [PATCH] fix: improve data package types This commit improves the types in the data package. - Adds new types `ThunkArgs` and `Thunk`. These types are intended to be used by consumers of the data package to define their own thunks. - Adds meta action creators to the `ActionCreatorsOf` type. - Adds the `dispatch` and `select` functions to the `DataRegistry` type. - Adds the `invalidate` action creators to the `ActionCreatorsOf` type. This allows consumers of the data package to have more complete type safety. Also, provides access to the invalidate resolution action creators, which are useful for complex data store manipulation. Adding new types as described above. Building the package types. --- packages/data/src/types.ts | 97 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 3 deletions(-) diff --git a/packages/data/src/types.ts b/packages/data/src/types.ts index 570bb1e1890ceb..49cbc8e18246ec 100644 --- a/packages/data/src/types.ts +++ b/packages/data/src/types.ts @@ -2,7 +2,16 @@ * External dependencies */ // eslint-disable-next-line no-restricted-imports -import type { combineReducers as reduxCombineReducers } from 'redux'; +import type { combineReducers as reduxCombineReducers, AnyAction } from 'redux'; + +/** + * Internal dependencies + */ +import type { + invalidateResolution, + invalidateResolutionForStore, + invalidateResolutionForStoreSelector, +} from './redux-store/metadata/actions'; type MapOf< T > = { [ name: string ]: T }; @@ -43,6 +52,34 @@ export interface ReduxStoreConfig< controls?: MapOf< Function >; } +type InvalidateResolution = typeof invalidateResolution; +type InvalidateResolutionForStore = typeof invalidateResolutionForStore; +type InvalidateResolutionForStoreSelector = + typeof invalidateResolutionForStoreSelector; + +type InvalidateResolutionAction = ReturnType< InvalidateResolution >; +type InvalidateResolutionForStoreAction = + ReturnType< InvalidateResolutionForStore >; +type InvalidateResolutionForStoreSelectorAction = + ReturnType< InvalidateResolutionForStoreSelector >; + +/** + * The action creators for metadata actions. + */ +type MetadataActionCreators = { + invalidateResolution: InvalidateResolution; + invalidateResolutionForStore: InvalidateResolutionForStore; + invalidateResolutionForStoreSelector: InvalidateResolutionForStoreSelector; +}; + +/** + * Metadata actions. + */ +type MetadataAction = + | InvalidateResolutionAction + | InvalidateResolutionForStoreAction + | InvalidateResolutionForStoreSelectorAction; + // Return type for the useSelect() hook. export type UseSelectReturn< F extends MapSelect | StoreDescriptor< any > > = F extends MapSelect @@ -158,7 +195,17 @@ export interface SelectorWithCustomCurrySignature { } export interface DataRegistry { - register: ( store: StoreDescriptor< any > ) => void; + register: ( store: StoreDescriptor< AnyConfig > ) => void; + dispatch: < S extends string | StoreDescriptor< AnyConfig > >( + storeNameOrDescriptor: S + ) => S extends StoreDescriptor< infer Config > + ? ActionCreatorsOf< Config > + : unknown; + select: < S extends string | StoreDescriptor< AnyConfig > >( + storeNameOrDescriptor: S + ) => S extends StoreDescriptor< infer Config > + ? CurriedSelectorsOf< Config > + : unknown; } export interface DataEmitter { @@ -173,11 +220,19 @@ export interface DataEmitter { export type ConfigOf< S > = S extends StoreDescriptor< infer C > ? C : never; -export type ActionCreatorsOf< Config extends AnyConfig > = +export type BaseActionCreatorsOf< Config extends AnyConfig > = Config extends ReduxStoreConfig< any, infer ActionCreators, any > ? PromisifiedActionCreators< ActionCreators > : never; +/** + * The action creators for a store config. + * + * Also includes metadata actions creators. + */ +type ActionCreatorsOf< Config extends AnyConfig > = + BaseActionCreatorsOf< Config > & MetadataActionCreators; + // Takes an object containing all action creators for a store and updates the // return type of each action creator to account for internal registry details -- // for example, dispatched actions are wrapped with a Promise. @@ -214,4 +269,40 @@ type SelectorsOf< Config extends AnyConfig > = Config extends ReduxStoreConfig< ? { [ name in keyof Selectors ]: Function } : never; +/** + * Thunk arguments. + * + * Used to type the arguments passed to a thunk function. + */ +export type ThunkArgs< + Action extends AnyAction, + S extends StoreDescriptor< AnyConfig >, +> = { + /** + * Dispatch an action to the store. + */ + dispatch: ( S extends StoreDescriptor< infer Config > + ? ActionCreatorsOf< Config > + : unknown ) & + ( ( action: Action | MetadataAction ) => void ); + + /** + * Selectors for the store. + */ + select: CurriedSelectorsOf< S >; + + /** + * The store registry object. + */ + registry: DataRegistry; +}; + +export type Thunk< + A extends AnyAction, + S extends StoreDescriptor< AnyConfig >, + T extends unknown = void, +> = T extends Awaited< infer R > + ? ( args: ThunkArgs< A, S > ) => Promise< R > + : ( args: ThunkArgs< A, S > ) => T; + export type combineReducers = typeof reduxCombineReducers;