Skip to content

Commit 7b3c0ac

Browse files
Justinmarkerikson
authored andcommitted
Fix PayloadAction inference (#138)
* Fix PayloadAction inference By wrapping the match in a single-element tuple, it prevents the conditional from being checked distributively, which otherwise has the effect of converting a union into an intersection when used with contra-variant types. * Add a descriptive comment for the esoteric tuple
1 parent 5d88849 commit 7b3c0ac

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

src/createSlice.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@ import { createSliceSelector, createSelectorName } from './sliceSelector'
55

66
/**
77
* An action creator atttached to a slice.
8+
*
9+
* The `P` generic is wrapped with a single-element tuple to prevent the
10+
* conditional from being checked distributively, thus preserving unions
11+
* of contra-variant types.
812
*/
9-
export type SliceActionCreator<P> = P extends void
13+
export type SliceActionCreator<P> = [P] extends [void]
1014
? () => PayloadAction<void>
1115
: (payload: P) => PayloadAction<P>
1216

type-tests/files/createSlice.typetest.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,16 @@ import {
6060
reducers: {
6161
increment: state => state + 1,
6262
decrement: state => state - 1,
63-
multiply: (state, action: PayloadAction<number>) => state * action.payload
63+
multiply: (state, { payload }: PayloadAction<number | number[]>) =>
64+
Array.isArray(payload)
65+
? payload.reduce((acc, val) => acc * val, state)
66+
: state * payload
6467
}
6568
})
6669

6770
counter.actions.increment()
6871
counter.actions.multiply(2)
72+
counter.actions.multiply([2, 3, 4])
6973

7074
// typings:expect-error
7175
counter.actions.multiply()

0 commit comments

Comments
 (0)