Closed
Description
TypeScript Version: 3.4.0-dev.20190312
Code
The following code throws the indicated error:
type Action<T extends string, P> = { readonly type: T; payload: P; }
type ActionCreator<T extends string, P> = { readonly type: T, (payload: P): Action<T, P> };
type Reducer<S, T extends string, P> = (state: S, action: Action<T, P>) => S;
type ReducerFor<S, AC> = AC extends ActionCreator<infer T, infer P> ? Reducer<S, T, P> : never;
declare function handleAction<AC>(action: AC, reducer: ReducerFor<{ value: string }, AC>): void;
declare const SomeAction: ActionCreator<"TestAction", string>;
handleAction(SomeAction, (state, action) => ({ ...state, value: action.payload }));
/* ^ resolved as Action<string, {}> ^ error appears here:
Type '{}' is not assignable to type 'string'.ts(2322)
The expected type comes from property 'value' which is declared here on type '{ value: string; }'
*/
As indicated in the comments, action
is being resolved as Action<string, {}>
instead of Action<"TestAction", string>
.
However, if I write the conditional inference in a different way, then this will work:
type ReducerFor<S, AC> =
Reducer<S, AC extends ActionCreator<infer T, any> ? T : never,
AC extends ActionCreator<any, infer P> ? P : never>;
declare const SomeAction: ActionCreator<"TestAction", string>;
handleActionTest(SomeAction, (state, action) => ({ ...state, value: action.payload }));
// ^ correctly resolved as Action<"TestAction", string>
Expected behavior:
The compiler should correctly handle the type inference and return a type of Action<"TestAction", string>
Actual behavior:
Incorrect type inference to Action<string, {}>
Playground Link:
Link with issue