UNPKG

@ngrx/store

Version:

RxJS powered Redux for Angular apps

62 lines (61 loc) 4.06 kB
import { ActionCreator, ActionCreatorProps, Creator, FunctionWithParametersType, NotAllowedCheck, Action } from './models'; type Join<Str extends string, Separator extends string = ' '> = Str extends `${infer First}${Separator}${infer Rest}` ? Join<`${First}${Rest}`, Separator> : Str; type CapitalizeWords<Str extends string> = Str extends `${infer First} ${infer Rest}` ? `${Capitalize<First>} ${CapitalizeWords<Rest>}` : Capitalize<Str>; type StringLiteralCheck<Str extends string, Name extends string> = string extends Str ? `${Name} must be a string literal type` : unknown; type UniqueEventNameCheck<EventNames extends string, EventName extends string> = ActionName<EventName> extends ActionName<Exclude<EventNames, EventName>> ? `${ActionName<EventName>} action is already defined` : unknown; type NotAllowedEventPropsCheck<PropsCreator extends ActionCreatorProps<unknown> | Creator> = PropsCreator extends ActionCreatorProps<infer Props> ? Props extends void ? unknown : NotAllowedCheck<Props & object> : PropsCreator extends Creator<any, infer Result> ? NotAllowedCheck<Result> : unknown; type EventCreator<PropsCreator extends ActionCreatorProps<unknown> | Creator, Type extends string> = PropsCreator extends ActionCreatorProps<infer Props> ? void extends Props ? ActionCreator<Type, () => Action<Type>> : ActionCreator<Type, (props: Props & NotAllowedCheck<Props & object>) => Props & Action<Type>> : PropsCreator extends Creator<infer Props, infer Result> ? FunctionWithParametersType<Props, Result & NotAllowedCheck<Result> & Action<Type>> & Action<Type> : never; type ActionName<EventName extends string> = Uncapitalize<Join<CapitalizeWords<EventName>>>; interface ActionGroupConfig<Source extends string, Events extends Record<string, ActionCreatorProps<unknown> | Creator>> { source: Source & StringLiteralCheck<Source, 'source'>; events: Events & { [EventName in keyof Events]: StringLiteralCheck<EventName & string, 'event name'> & UniqueEventNameCheck<keyof Events & string, EventName & string> & NotAllowedEventPropsCheck<Events[EventName]>; }; } type ActionGroup<Source extends string, Events extends Record<string, ActionCreatorProps<unknown> | Creator>> = { [EventName in keyof Events as ActionName<EventName & string>]: EventCreator<Events[EventName], `[${Source}] ${EventName & string}`>; }; /** * @description * A function that creates a group of action creators with the same source. * * @param config An object that contains a source and dictionary of events. * An event is a key-value pair of an event name and event props. * @returns A dictionary of action creators. * The name of each action creator is created by camel casing the event name. * The type of each action is created using the "[Source] Event Name" pattern. * * @usageNotes * * ```ts * const authApiActions = createActionGroup({ * source: 'Auth API', * events: { * // defining events with payload using the `props` function * 'Login Success': props<{ userId: number; token: string }>(), * 'Login Failure': props<{ error: string }>(), * * // defining an event without payload using the `emptyProps` function * 'Logout Success': emptyProps(), * * // defining an event with payload using the props factory * 'Logout Failure': (error: Error) => ({ error }), * }, * }); * * // action type: "[Auth API] Login Success" * authApiActions.loginSuccess({ userId: 10, token: 'ngrx' }); * * // action type: "[Auth API] Login Failure" * authApiActions.loginFailure({ error: 'Login Failure!' }); * * // action type: "[Auth API] Logout Success" * authApiActions.logoutSuccess(); * * // action type: "[Auth API] Logout Failure"; * authApiActions.logoutFailure(new Error('Logout Failure!')); * ``` */ export declare function createActionGroup<Source extends string, Events extends Record<string, ActionCreatorProps<unknown> | Creator>>(config: ActionGroupConfig<Source, Events>): ActionGroup<Source, Events>; export declare function emptyProps(): ActionCreatorProps<void>; export {};