47 lines
1.2 KiB
TypeScript
47 lines
1.2 KiB
TypeScript
import { Action, ActionCreator, Middleware, Reducer } from 'redux';
|
|
|
|
export type Dux<
|
|
STATE = any,
|
|
ACTIONS extends Record<string, ActionCreator<string>> = {},
|
|
> = Partial<{
|
|
initialState: STATE;
|
|
actions: ACTIONS;
|
|
selectors: Record<string, (state: STATE) => any>;
|
|
reducer: (
|
|
state: STATE,
|
|
action: ReturnType<ACTIONS[keyof ACTIONS]>,
|
|
) => STATE;
|
|
effects: Middleware[];
|
|
reactions: ((...args: any[]) => void)[];
|
|
}>;
|
|
|
|
type ActionsOf<DUX> = DUX extends { actions: infer A } ? A : {};
|
|
type SelectorsOf<DUX> = DUX extends { selectors: infer A } ? A : {};
|
|
|
|
export type AggregateActions<A, S> = UnionToIntersection<
|
|
ActionsOf<S[keyof S]> | A
|
|
>;
|
|
|
|
type BaseSelector<F extends (...args: any) => any, STATE> = (
|
|
state: STATE,
|
|
) => ReturnType<F>;
|
|
|
|
type BaseSelectors<S extends Record<string, any>, STATE> = {
|
|
[key in keyof S]: BaseSelector<S[key], STATE>;
|
|
};
|
|
|
|
export type AggregateSelectors<
|
|
S extends Record<string, (...args: any) => any>,
|
|
SUBS extends Record<string, Dux>,
|
|
STATE = {},
|
|
> = BaseSelectors<
|
|
UnionToIntersection<SelectorsOf<SUBS[keyof SUBS]> | S>,
|
|
STATE
|
|
>;
|
|
|
|
export type UnionToIntersection<U> = (
|
|
U extends any ? (k: U) => void : never
|
|
) extends (k: infer I) => void
|
|
? I
|
|
: never;
|