You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
### Alternative to using a literally-typed `action.type`
112
112
113
-
If you are using `action.type` as discriminator on a discriminated union, for example to correctly type your payload in `case` statements, you might be interested in this alternative:
113
+
If you are using `action.type` as a discriminator on a discriminated union, for example to correctly type your payload in `case` statements, you might be interested in this alternative:
114
114
115
115
Created action creators have a `match` method that acts as a [type predicate](https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates):
116
116
@@ -128,7 +128,7 @@ This `match` method is also very useful in combination with `redux-observable` a
128
128
129
129
## `createReducer`
130
130
131
-
The default way of calling `createReducer` would be with a map object, like this:
131
+
The default way of calling `createReducer` would be with a "lookup table" / "map object", like this:
132
132
133
133
```typescript
134
134
createReducer(0, {
@@ -159,7 +159,7 @@ As an alternative, RTK includes a type-safe reducer builder API.
159
159
160
160
Instead of using a simple object as an argument to `createReducer`, you can also use a callback that receives a `ActionReducerMapBuilder` instance:
You might have noticed that it is not a good idea to pass your `SliceState` type as a generic to `createSlice`. This is due to the fact that in almost all cases, follow-up generic parameters to `createSlice` need to be inferred, and TypeScript cannot mix explicit declaration and inference of generic types within the same "generic block".
219
219
220
-
Instead, you can use the construct`initialState: myInitialState as SliceState`.
220
+
The standard approach is to declare an interface or type for your state, create an initial state value that uses that type, and pass the initial state value to `createSlice. You can also use the construct`initialState: myInitialState as SliceState`.
### On the "type" property of slice action Reducers
271
+
### Generated Action Types for Slices
264
272
265
-
As TS cannot combine two string literals (`slice.name` and the key of `actionMap`) into a new literal, all actionCreators created by createSlice are of type 'string'. This is usually not a problem, as these types are only rarely used as literals.
273
+
As TS cannot combine two string literals (`slice.name` and the key of `actionMap`) into a new literal, all actionCreators created by `createSlice` are of type 'string'. This is usually not a problem, as these types are only rarely used as literals.
266
274
267
-
In most cases that type would be required as a literal, the `slice.action.myAction.match`[type predicate](https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates) should prove as a viable alternative:
275
+
In most cases that `type` would be required as a literal, the `slice.action.myAction.match`[type predicate](https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates) should be a viable alternative:
268
276
269
-
```typescript
277
+
```ts {10}
270
278
const slice =createSlice({
271
279
name: 'test',
272
280
initialState: 0,
@@ -286,7 +294,44 @@ If you actually _need_ that type, unfortunately there is no other way than manua
286
294
287
295
### Type safety with `extraReducers`
288
296
289
-
Like in `createReducer`, the `extraReducers` map object is not easy to fully type. So, like with `createReducer`, you may also use the "builder callback" approach for defining the reducer object argument. See [the `createReducer` section above](#createreducer) for an example.
297
+
Reducer lookup tables that map an action `type` string to a reducer function are not easy to fully type correctly. This affects both `createReducer` and the `extraReducers` argument for `createSlice`. So, like with `createReducer`, [you may also use the "builder callback" approach](#building-type-safe-reducer-argument-objects) for defining the reducer object argument.
298
+
299
+
This is particularly useful when a slice reducer needs to handle action types generated by other slices, or generated by specific calls to `createAction` (such as the actions generated by [`createAsyncThunk`](../api/createAsyncThunk.md)).
In the most common use cases, you might not need any special types for `createAsyncThunk`.
353
-
Just provide a type for the first argument to the `payloadCreator` argument as you would for any function argument and the resulting thunk will accept the same type as input parameter.
397
+
In the most common use cases, you should not need to explicitly declare any types for the `createAsyncThunk` call itself.
398
+
399
+
Just provide a type for the first argument to the `payloadCreator` argument as you would for any function argument, and the resulting thunk will accept the same type as input parameter.
354
400
The return type of the `payloadCreator` will also be reflected in all generated action types.
If you want to use `thunkApi.dispatch`, `thunkApi.getStore()` or `thunkApi.extra` from within the `payloadCreator`, you will need to define some generic arguments, as the types for these arguments cannot be inferred. Also, as TS cannot mix explicit and inferred generic parameters, from this point on you'll have to define the `Returned` and `ThunkArg` generic parameter as well.
422
+
The second argument to the `payloadCreator` is a `thunkApi` object containing references to the `dispatch`, `getState`, and `extra` arguments from the thunk middleware. If you want to use these from within the `payloadCreator`, you will need to define some generic arguments, as the types for these arguments cannot be inferred. Also, as TS cannot mix explicit and inferred generic parameters, from this point on you'll have to define the `Returned` and `ThunkArg` generic parameter as well.
377
423
378
-
```ts
424
+
To define the types for these arguments, pass an object as the third generic argument, with type declarations for some or all of these fields: `{dispatch?, state?, extra?}`.
While this notation for `state`, `dispatch` and `extra` might seem uncommon at first, it allows you to provide only the types for these you actually need - so for example, if you are not accessing `getState` within your `actionProducer`, there is no need to provide a type for `state`.
447
+
While this notation for `state`, `dispatch` and `extra` might seem uncommon at first, it allows you to provide only the types for these you actually need - so for example, if you are not accessing `getState` within your `payloadCreator`, there is no need to provide a type for `state`.
400
448
401
449
## `createEntityAdapter`
402
450
403
-
Typing `createEntityAdapter` only requires you to specify the entity type as the only generic argument.
451
+
Typing `createEntityAdapter` only requires you to specify the entity type as the single generic argument.
404
452
405
-
So the example from the `createEntityAdapter` documentation would look like this in TypeScript:
453
+
The example from the `createEntityAdapter` documentation would look like this in TypeScript:
0 commit comments