0
# Action Creators
1
2
Action creators provide type-safe action creation with payload validation and support for organizing related actions into groups. They reduce boilerplate and ensure type safety throughout the application.
3
4
## Capabilities
5
6
### Create Action
7
8
Creates individual action creators with optional payloads.
9
10
```typescript { .api }
11
/**
12
* Creates a configured action creator function that returns an Action
13
* @param type - Describes the action that will be dispatched
14
* @returns ActionCreator function with type property
15
*/
16
function createAction<T extends string>(type: T): ActionCreator<T, () => Action<T>>;
17
18
/**
19
* Creates a configured action creator function with props payload
20
* @param type - Describes the action that will be dispatched
21
* @param config - Action creator props configuration
22
* @returns ActionCreator function that accepts payload
23
*/
24
function createAction<T extends string, P extends object>(
25
type: T,
26
config: ActionCreatorProps<P> & NotAllowedCheck<P>
27
): ActionCreator<T, (props: P & NotAllowedCheck<P>) => P & Action<T>>;
28
29
/**
30
* Creates a configured action creator function with custom creator
31
* @param type - Describes the action that will be dispatched
32
* @param creator - Custom creator function
33
* @returns ActionCreator with custom parameters and return type
34
*/
35
function createAction<T extends string, P extends any[], R extends object>(
36
type: T,
37
creator: Creator<P, R & NotAllowedCheck<R>>
38
): FunctionWithParametersType<P, R & Action<T>> & Action<T>;
39
```
40
41
**Usage Examples:**
42
43
```typescript
44
import { createAction, props } from "@ngrx/store";
45
46
// Simple action without payload
47
export const increment = createAction('[Counter] Increment');
48
export const reset = createAction('[Counter] Reset');
49
50
// Action with props payload
51
export const setValue = createAction(
52
'[Counter] Set Value',
53
props<{ value: number }>()
54
);
55
56
export const loadUser = createAction(
57
'[User] Load User',
58
props<{ userId: string }>()
59
);
60
61
export const loginSuccess = createAction(
62
'[Auth] Login Success',
63
props<{ user: User; token: string }>()
64
);
65
66
// Action with custom creator function
67
export const searchResults = createAction(
68
'[Search] Results',
69
(query: string, results: SearchResult[], timestamp = Date.now()) => ({
70
query,
71
results,
72
timestamp,
73
resultCount: results.length
74
})
75
);
76
77
// Usage in components
78
store.dispatch(increment());
79
store.dispatch(setValue({ value: 42 }));
80
store.dispatch(loadUser({ userId: 'user-123' }));
81
store.dispatch(searchResults('angular', searchData));
82
```
83
84
### Props Function
85
86
Defines payload structure for action creators.
87
88
```typescript { .api }
89
/**
90
* Creates props configuration for action creators
91
* @returns ActionCreatorProps for type-safe payload definition
92
*/
93
function props<P extends SafeProps, SafeProps = NotAllowedInPropsCheck<P>>(): ActionCreatorProps<P>;
94
```
95
96
### Union Function
97
98
Creates union types from multiple action creators for reducer type inference.
99
100
```typescript { .api }
101
/**
102
* Creates union type from action creators for type inference
103
* @param creators - Dictionary of action creators
104
* @returns Union type of all action creator return types
105
*/
106
function union<C extends { [key: string]: ActionCreator<string, Creator> }>(
107
creators: C
108
): ReturnType<C[keyof C]>;
109
```
110
111
**Usage Examples:**
112
113
```typescript
114
// Define action creators
115
const counterActions = {
116
increment: createAction('[Counter] Increment'),
117
decrement: createAction('[Counter] Decrement'),
118
setValue: createAction('[Counter] Set Value', props<{ value: number }>())
119
};
120
121
// Create union type for reducer
122
type CounterActions = ReturnType<typeof union<typeof counterActions>>;
123
124
// Use in reducer
125
const counterReducer = createReducer(
126
initialState,
127
on(counterActions.increment, state => ({ ...state, count: state.count + 1 })),
128
on(counterActions.setValue, (state, { value }) => ({ ...state, count: value }))
129
);
130
```
131
132
### Create Action Group
133
134
Creates multiple related actions with a shared source prefix.
135
136
```typescript { .api }
137
/**
138
* Creates a group of action creators with the same source
139
* @param config - Configuration object with source and events
140
* @returns Dictionary of action creators with camelCase names
141
*/
142
function createActionGroup<Source extends string, Events extends Record<string, ActionCreatorProps<unknown> | Creator>>(
143
config: ActionGroupConfig<Source, Events>
144
): ActionGroup<Source, Events>;
145
146
interface ActionGroupConfig<Source extends string, Events> {
147
/** Source prefix for all actions in the group */
148
source: Source;
149
/** Dictionary of event names and their payload configurations */
150
events: Events;
151
}
152
```
153
154
**Usage Examples:**
155
156
```typescript
157
import { createActionGroup, props, emptyProps } from "@ngrx/store";
158
159
// Create action group for API operations
160
export const AuthApiActions = createActionGroup({
161
source: 'Auth API',
162
events: {
163
// Action with payload using props
164
'Login Success': props<{ user: User; token: string }>(),
165
'Login Failure': props<{ error: string }>(),
166
167
// Action without payload using emptyProps
168
'Logout Success': emptyProps(),
169
170
// Action with custom creator function
171
'Session Expired': (reason: string, timestamp = Date.now()) => ({
172
reason,
173
timestamp
174
}),
175
},
176
});
177
178
// Generated action creators (camelCase names):
179
// AuthApiActions.loginSuccess({ user, token })
180
// AuthApiActions.loginFailure({ error })
181
// AuthApiActions.logoutSuccess()
182
// AuthApiActions.sessionExpired('timeout')
183
184
// Action types are formatted as "[Source] Event Name":
185
// "[Auth API] Login Success"
186
// "[Auth API] Login Failure"
187
// "[Auth API] Logout Success"
188
// "[Auth API] Session Expired"
189
190
// Usage in effects or components
191
store.dispatch(AuthApiActions.loginSuccess({ user: userData, token: authToken }));
192
store.dispatch(AuthApiActions.loginFailure({ error: 'Invalid credentials' }));
193
store.dispatch(AuthApiActions.logoutSuccess());
194
```
195
196
### Empty Props
197
198
Creates empty props configuration for actions without payload.
199
200
```typescript { .api }
201
/**
202
* Creates empty props configuration for actions without payload
203
* @returns ActionCreatorProps<void> for parameterless actions
204
*/
205
function emptyProps(): ActionCreatorProps<void>;
206
```
207
208
## Type Definitions
209
210
### Core Action Types
211
212
```typescript { .api }
213
/**
214
* Basic action interface with type property
215
*/
216
interface Action<Type extends string = string> {
217
type: Type;
218
}
219
220
/**
221
* Function that returns an object in the shape of Action interface
222
*/
223
type Creator<P extends any[] = any[], R extends object = object> =
224
FunctionWithParametersType<P, R>;
225
226
/**
227
* Action creator function with type property
228
*/
229
type ActionCreator<T extends string = string, C extends Creator = Creator> =
230
C & Action<T>;
231
232
/**
233
* Props configuration for action creators
234
*/
235
interface ActionCreatorProps<T> {
236
_as: 'props';
237
_p: T;
238
}
239
240
/**
241
* Extract action type from action creator
242
*/
243
type ActionType<A> = A extends ActionCreator<infer T, infer C>
244
? ReturnType<C> & { type: T }
245
: never;
246
247
/**
248
* Function with specific parameters and return type
249
*/
250
type FunctionWithParametersType<P extends unknown[], R = void> =
251
(...args: P) => R;
252
```
253
254
## Validation and Type Safety
255
256
Action creators include compile-time validation to prevent common mistakes:
257
258
```typescript
259
// ❌ These will cause TypeScript errors:
260
261
// Arrays not allowed in props
262
const badAction1 = createAction(
263
'[Bad] Action',
264
props<string[]>() // Error: arrays not allowed
265
);
266
267
// Type property not allowed in props
268
const badAction2 = createAction(
269
'[Bad] Action',
270
props<{ type: string; data: any }>() // Error: type property not allowed
271
);
272
273
// Empty objects not allowed in props
274
const badAction3 = createAction(
275
'[Bad] Action',
276
props<{}>() // Error: empty objects not allowed
277
);
278
279
// ✅ Correct usage:
280
const goodAction = createAction(
281
'[Good] Action',
282
props<{ data: any; count: number }>()
283
);
284
```
285
286
## Best Practices
287
288
1. **Use descriptive action types**: Include the source/feature and specific operation
289
2. **Group related actions**: Use `createActionGroup` for related API operations
290
3. **Type safety**: Always use `props<T>()` for payload validation
291
4. **Consistent naming**: Follow the pattern `[Source] Operation` for action types
292
5. **Avoid large payloads**: Keep action payloads minimal and normalized