1 | import type { Action, AnyAction, ActionCreator } from 'redux'
|
2 | import type {
|
3 | PayloadAction,
|
4 | PayloadActionCreator,
|
5 | ActionCreatorWithoutPayload,
|
6 | ActionCreatorWithOptionalPayload,
|
7 | ActionCreatorWithPayload,
|
8 | ActionCreatorWithNonInferrablePayload,
|
9 | ActionCreatorWithPreparedPayload,
|
10 | } from '@reduxjs/toolkit'
|
11 | import { createAction } from '@reduxjs/toolkit'
|
12 | import type { IsAny } from '@internal/tsHelpers'
|
13 | import { expectType } from './helpers'
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | {
|
21 | const action: PayloadAction<number> = { type: '', payload: 5 }
|
22 | const numberPayload: number = action.payload
|
23 |
|
24 |
|
25 | const stringPayload: string = action.payload
|
26 | }
|
27 |
|
28 |
|
29 |
|
30 |
|
31 | {
|
32 |
|
33 | const action: PayloadAction = { type: '', payload: 5 }
|
34 |
|
35 | const numberPayload: number = action.payload
|
36 |
|
37 | const stringPayload: string = action.payload
|
38 | }
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | {
|
44 | const action: PayloadAction<number> = { type: '', payload: 5 }
|
45 |
|
46 |
|
47 | const action2: PayloadAction = { type: 1, payload: 5 }
|
48 | }
|
49 |
|
50 |
|
51 |
|
52 |
|
53 | {
|
54 | const action: PayloadAction<number> = { type: '', payload: 5 }
|
55 | const stringAction: Action<string> = action
|
56 | }
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 | {
|
65 | const actionCreator = Object.assign(
|
66 | (payload?: number) => ({
|
67 | type: 'action',
|
68 | payload,
|
69 | }),
|
70 | { type: 'action' }
|
71 | ) as PayloadActionCreator<number | undefined>
|
72 |
|
73 | expectType<PayloadAction<number | undefined>>(actionCreator(1))
|
74 | expectType<PayloadAction<number | undefined>>(actionCreator())
|
75 | expectType<PayloadAction<number | undefined>>(actionCreator(undefined))
|
76 |
|
77 |
|
78 | expectType<PayloadAction<number>>(actionCreator())
|
79 |
|
80 | expectType<PayloadAction<undefined>>(actionCreator(1))
|
81 | }
|
82 |
|
83 |
|
84 |
|
85 |
|
86 | {
|
87 | const payloadActionCreator = Object.assign(
|
88 | (payload?: number) => ({
|
89 | type: 'action',
|
90 | payload,
|
91 | }),
|
92 | { type: 'action' }
|
93 | ) as PayloadActionCreator
|
94 | const actionCreator: ActionCreator<AnyAction> = payloadActionCreator
|
95 |
|
96 | const payloadActionCreator2 = Object.assign(
|
97 | (payload?: number) => ({
|
98 | type: 'action',
|
99 | payload: payload || 1,
|
100 | }),
|
101 | { type: 'action' }
|
102 | ) as PayloadActionCreator<number>
|
103 |
|
104 | const actionCreator2: ActionCreator<PayloadAction<number>> =
|
105 | payloadActionCreator2
|
106 | }
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 | {
|
114 | const increment = createAction<number, 'increment'>('increment')
|
115 | const n: number = increment(1).payload
|
116 |
|
117 |
|
118 | increment('').payload
|
119 | }
|
120 |
|
121 |
|
122 |
|
123 |
|
124 | {
|
125 | const increment = createAction('increment')
|
126 |
|
127 | const n: number = increment(1).payload
|
128 | }
|
129 |
|
130 |
|
131 |
|
132 | {
|
133 | const increment = createAction<number, 'increment'>('increment')
|
134 | const n: string = increment(1).type
|
135 | const s: 'increment' = increment(1).type
|
136 |
|
137 |
|
138 | const r: 'other' = increment(1).type
|
139 |
|
140 | const q: number = increment(1).type
|
141 | }
|
142 |
|
143 |
|
144 |
|
145 |
|
146 | {
|
147 | const strLenAction = createAction('strLen', (payload: string) => ({
|
148 | payload: payload.length,
|
149 | }))
|
150 |
|
151 | expectType<string>(strLenAction('test').type)
|
152 | }
|
153 |
|
154 |
|
155 |
|
156 |
|
157 | {
|
158 | const strLenAction = createAction('strLen', (payload: string) => ({
|
159 | payload: payload.length,
|
160 | }))
|
161 | expectType<number>(strLenAction('test').payload)
|
162 |
|
163 |
|
164 | expectType<string>(strLenAction('test').payload)
|
165 |
|
166 | const error: any = strLenAction('test').error
|
167 | }
|
168 |
|
169 |
|
170 |
|
171 |
|
172 | {
|
173 | const strLenMetaAction = createAction('strLenMeta', (payload: string) => ({
|
174 | payload,
|
175 | meta: payload.length,
|
176 | }))
|
177 |
|
178 | expectType<number>(strLenMetaAction('test').meta)
|
179 |
|
180 |
|
181 | expectType<string>(strLenMetaAction('test').meta)
|
182 |
|
183 | const error: any = strLenMetaAction('test').error
|
184 | }
|
185 |
|
186 |
|
187 |
|
188 |
|
189 | {
|
190 | const boolErrorAction = createAction('boolError', (payload: string) => ({
|
191 | payload,
|
192 | error: true,
|
193 | }))
|
194 |
|
195 | expectType<boolean>(boolErrorAction('test').error)
|
196 |
|
197 |
|
198 | expectType<string>(boolErrorAction('test').error)
|
199 | }
|
200 |
|
201 |
|
202 |
|
203 |
|
204 | {
|
205 | const strErrorAction = createAction('strError', (payload: string) => ({
|
206 | payload,
|
207 | error: 'this is an error',
|
208 | }))
|
209 |
|
210 | expectType<string>(strErrorAction('test').error)
|
211 |
|
212 |
|
213 | expectType<boolean>(strErrorAction('test').error)
|
214 | }
|
215 |
|
216 |
|
217 |
|
218 |
|
219 | {
|
220 | const action = createAction<{ input?: string }>('ACTION')
|
221 | const t: string | undefined = action({ input: '' }).payload.input
|
222 |
|
223 |
|
224 | const u: number = action({ input: '' }).payload.input
|
225 |
|
226 | const v: number = action({ input: 3 }).payload.input
|
227 | }
|
228 |
|
229 |
|
230 |
|
231 |
|
232 | {
|
233 | const oops = createAction('oops', (x: any) => ({
|
234 | payload: x,
|
235 | error: x,
|
236 | meta: x,
|
237 | }))
|
238 |
|
239 | type Ret = ReturnType<typeof oops>
|
240 |
|
241 | const payload: IsAny<Ret['payload'], true, false> = true
|
242 | const error: IsAny<Ret['error'], true, false> = true
|
243 | const meta: IsAny<Ret['meta'], true, false> = true
|
244 |
|
245 |
|
246 | const payloadNotAny: IsAny<Ret['payload'], true, false> = false
|
247 |
|
248 | const errorNotAny: IsAny<Ret['error'], true, false> = false
|
249 |
|
250 | const metaNotAny: IsAny<Ret['meta'], true, false> = false
|
251 | }
|
252 |
|
253 |
|
254 |
|
255 |
|
256 | {
|
257 |
|
258 | {
|
259 | const actionCreator = createAction<string, 'test'>('test')
|
260 | const x: Action<unknown> = {} as any
|
261 | if (actionCreator.match(x)) {
|
262 | expectType<'test'>(x.type)
|
263 | expectType<string>(x.payload)
|
264 | } else {
|
265 |
|
266 | expectType<'test'>(x.type)
|
267 |
|
268 | expectType<any>(x.payload)
|
269 | }
|
270 | }
|
271 |
|
272 |
|
273 | {
|
274 | const actionCreator = createAction<string | undefined, 'test'>('test')
|
275 | const x: Action<unknown> = {} as any
|
276 | if (actionCreator.match(x)) {
|
277 | expectType<'test'>(x.type)
|
278 | expectType<string | undefined>(x.payload)
|
279 | }
|
280 | }
|
281 |
|
282 |
|
283 | {
|
284 | const actionCreator = createAction('test')
|
285 | const x: Action<unknown> = {} as any
|
286 | if (actionCreator.match(x)) {
|
287 | expectType<'test'>(x.type)
|
288 |
|
289 | expectType<{}>(x.payload)
|
290 | }
|
291 | }
|
292 |
|
293 |
|
294 | {
|
295 | const actionCreator = createAction('test', () => ({
|
296 | payload: '',
|
297 | meta: '',
|
298 | error: false,
|
299 | }))
|
300 | const x: Action<unknown> = {} as any
|
301 | if (actionCreator.match(x)) {
|
302 | expectType<'test'>(x.type)
|
303 | expectType<string>(x.payload)
|
304 | expectType<string>(x.meta)
|
305 | expectType<boolean>(x.error)
|
306 |
|
307 | expectType<number>(x.payload)
|
308 |
|
309 | expectType<number>(x.meta)
|
310 |
|
311 | expectType<number>(x.error)
|
312 | }
|
313 | }
|
314 |
|
315 | {
|
316 | const actionCreator = createAction<string, 'test'>('test')
|
317 | const x: Array<Action<unknown>> = []
|
318 | expectType<Array<PayloadAction<string, 'test'>>>(
|
319 | x.filter(actionCreator.match)
|
320 | )
|
321 |
|
322 | expectType<Array<PayloadAction<number, 'test'>>>(
|
323 |
|
324 | x.filter(actionCreator.match)
|
325 | )
|
326 | }
|
327 | }
|
328 | {
|
329 | expectType<ActionCreatorWithOptionalPayload<string | undefined>>(
|
330 | createAction<string | undefined>('')
|
331 | )
|
332 | expectType<ActionCreatorWithoutPayload>(createAction<void>(''))
|
333 | expectType<ActionCreatorWithNonInferrablePayload>(createAction(''))
|
334 | expectType<ActionCreatorWithPayload<string>>(createAction<string>(''))
|
335 | expectType<ActionCreatorWithPreparedPayload<[0], 1, '', 2, 3>>(
|
336 | createAction('', (_: 0) => ({
|
337 | payload: 1 as 1,
|
338 | error: 2 as 2,
|
339 | meta: 3 as 3,
|
340 | }))
|
341 | )
|
342 | const anyCreator = createAction<any>('')
|
343 | expectType<ActionCreatorWithPayload<any>>(anyCreator)
|
344 | type AnyPayload = ReturnType<typeof anyCreator>['payload']
|
345 | expectType<IsAny<AnyPayload, true, false>>(true)
|
346 | }
|