export type Dict<T> = Record<string, T>;

export type UnionToIntersection<U> = (
    U extends any ? (k: U) => void : never
) extends (k: infer I) => void
    ? I
    : never;

type Subdux<TState = any> = {
    initial: TState;
};

type StateOf<D> = D extends { initial: infer I } ? I : unknown;
type ActionsOf<C> = C extends { actions: infer A }
    ? {
          [K in keyof A]: Function;
      }
    : {};

type Subduxes = Record<string, Subdux>;

export type DuxStateSubduxes<C> = C extends { '*': infer I }
    ? {
          [key: string]: StateOf<I>;
          [index: number]: StateOf<I>;
      }
    : { [K in keyof C]: StateOf<C[K]> };

export type AggregateDuxState<TState, TSubduxes> = TState &
    DuxStateSubduxes<TSubduxes>;

type DuxActionsSubduxes<C> = C extends object ? ActionsOf<C[keyof C]> : unknown;

type ItemsOf<C> = C extends object ? C[keyof C] : unknown;

export type AggregateDuxActions<TActions, TSubduxes> = TActions &
    UnionToIntersection<ActionsOf<ItemsOf<TSubduxes>>>;
