@@ -12,12 +12,13 @@ import type { ThunkDispatch } from 'redux-thunk'
12
12
import type { AxiosError } from 'axios'
13
13
import apiRequest from 'axios'
14
14
import type { IsAny , IsUnknown } from '@internal/tsHelpers'
15
- import { expectType } from './helpers'
15
+ import { expectExactType , expectType } from './helpers'
16
16
import type {
17
17
AsyncThunkFulfilledActionCreator ,
18
18
AsyncThunkRejectedActionCreator ,
19
19
} from '@internal/createAsyncThunk'
20
20
21
+ const ANY = { } as any
21
22
const defaultDispatch = ( ( ) => { } ) as ThunkDispatch < { } , any , AnyAction >
22
23
const anyAction = { type : 'foo' } as AnyAction
23
24
@@ -598,53 +599,74 @@ const anyAction = { type: 'foo' } as AnyAction
598
599
}
599
600
600
601
{
601
- const typedCAT = createAsyncThunk . forTypes < {
602
+ const typedCAT = createAsyncThunk . withTypes < {
602
603
state : RootState
603
604
dispatch : AppDispatch
605
+ rejectValue : string
604
606
} > ( )
605
607
608
+ // inferred usage
606
609
const thunk = typedCAT ( 'foo' , ( arg : number , api ) => {
607
610
// correct getState Type
608
611
const test1 : number = api . getState ( ) . foo . value
609
612
// correct dispatch type
610
- const test2 : number = api . dispatch (
611
- ( dispatch , getState ) => getState ( ) . foo . value
612
- )
613
+ const test2 : number = api . dispatch ( ( dispatch , getState ) => {
614
+ expectExactType <
615
+ ThunkDispatch < { foo : { value : number } } , undefined , AnyAction >
616
+ > ( ANY ) ( dispatch )
617
+ expectExactType < ( ) => { foo : { value : number } } > ( ANY ) ( getState )
618
+ return getState ( ) . foo . value
619
+ } )
620
+
621
+ if ( 1 < 2 )
622
+ // @ts -expect-error
623
+ return api . rejectWithValue ( 5 )
624
+ if ( 1 < 2 ) return api . rejectWithValue ( 'test' )
613
625
return test1 + test2
614
626
} )
615
627
628
+ // usage with two generics
616
629
const thunk2 = typedCAT < number , string > ( 'foo' , ( arg , api ) => {
630
+ expectExactType ( '' as string ) ( arg )
617
631
// correct getState Type
618
632
const test1 : number = api . getState ( ) . foo . value
619
633
// correct dispatch type
620
- const test2 : number = api . dispatch (
621
- ( dispatch , getState ) => getState ( ) . foo . value
622
- )
634
+ const test2 : number = api . dispatch ( ( dispatch , getState ) => {
635
+ expectExactType <
636
+ ThunkDispatch < { foo : { value : number } } , undefined , AnyAction >
637
+ > ( ANY ) ( dispatch )
638
+ expectExactType < ( ) => { foo : { value : number } } > ( ANY ) ( getState )
639
+ return getState ( ) . foo . value
640
+ } )
641
+ if ( 1 < 2 )
642
+ // @ts -expect-error
643
+ return api . rejectWithValue ( 5 )
644
+ if ( 1 < 2 ) return api . rejectWithValue ( 'test' )
623
645
return test1 + test2
624
646
} )
625
647
626
- const thunk3 = typedCAT <
627
- number ,
628
- string ,
629
- // @ts -expect-error TODO
630
- // right now this still errors because
631
- // it does not contain `state` and `dispatch`
632
- {
633
- rejectValue : string
634
- }
635
- > ( 'foo' , ( arg , api ) => {
636
- // correct getState Type
637
- const test1 : number = api . getState ( ) . foo . value
638
- // correct dispatch type
639
- const test2 : number = api . dispatch (
640
- ( dispatch , getState ) => getState ( ) . foo . value
641
- )
642
- if ( 1 < 2 ) {
643
- // TODO: @ts -expect-error
644
- return api . rejectWithValue ( 5 )
648
+ // usage with config override generic
649
+ const thunk3 = typedCAT < number , string , { rejectValue : number } > (
650
+ 'foo' ,
651
+ ( arg , api ) => {
652
+ expectExactType ( '' as string ) ( arg )
653
+ // correct getState Type
654
+ const test1 : number = api . getState ( ) . foo . value
655
+ // correct dispatch type
656
+ const test2 : number = api . dispatch ( ( dispatch , getState ) => {
657
+ expectExactType <
658
+ ThunkDispatch < { foo : { value : number } } , undefined , AnyAction >
659
+ > ( ANY ) ( dispatch )
660
+ expectExactType < ( ) => { foo : { value : number } } > ( ANY ) ( getState )
661
+ return getState ( ) . foo . value
662
+ } )
663
+ if ( 1 < 2 ) return api . rejectWithValue ( 5 )
664
+ if ( 1 < 2 )
665
+ // @ts -expect-error
666
+ return api . rejectWithValue ( 'test' )
667
+ return 5
645
668
}
646
- return api . rejectWithValue ( 5 )
647
- } )
669
+ )
648
670
649
671
const slice = createSlice ( {
650
672
name : 'foo' ,
@@ -655,13 +677,21 @@ const anyAction = { type: 'foo' } as AnyAction
655
677
. addCase ( thunk . fulfilled , ( state , action ) => {
656
678
state . value += action . payload
657
679
} )
680
+ . addCase ( thunk . rejected , ( state , action ) => {
681
+ expectExactType ( '' as string | undefined ) ( action . payload )
682
+ } )
658
683
. addCase ( thunk2 . fulfilled , ( state , action ) => {
659
684
state . value += action . payload
660
685
} )
661
- . addCase ( thunk3 . rejected , ( state , action ) => {
662
- // @ts -expect-error TODO does not have the right type yet because the config was incomplete
686
+ . addCase ( thunk2 . rejected , ( state , action ) => {
687
+ expectExactType ( '' as string | undefined ) ( action . payload )
688
+ } )
689
+ . addCase ( thunk3 . fulfilled , ( state , action ) => {
663
690
state . value += action . payload
664
691
} )
692
+ . addCase ( thunk3 . rejected , ( state , action ) => {
693
+ expectExactType ( 0 as number | undefined ) ( action . payload )
694
+ } )
665
695
} ,
666
696
} )
667
697
0 commit comments