export type ActionGenerator<TType extends string = string, TPayloadGen = undefined> = {
    type: TType;
} & (TPayloadGen extends Function
    ? (...args: Parameters<TPayloadGen>) => {
          type: TType;
          payload: ReturnType<TPayloadGen>;
      }
    : (...args: any[]) => { type: TType; payload?: unknown });

interface Action {
    <T extends string = string>(actionType: T): ActionGenerator<T>;
    <T extends string = string, F extends Function = Function>(
        actionType: T,
        payloadGen: F
    ): ActionGenerator<T, F>;
}

/**
 * Creates an action generator.
 */
export const action: Action;

/**
 * Utility type for payload generators that are passthroughs.
 */
export type Payload<T = unknown> = (arg: T) => T;
