Closed
Description
TypeScript Version:
2.8.1, 2.9.2, 3.0.0-dev.20180628
Search Terms:
conditional type inference
Code
// Don't know what causes the problem so cannot come up with a shorter sample
type ActionType<P> = string & { attachPayloadTypeHack?: P & never }
/*
// irrelevant type to reproduce my issue
// but gives context that action might have no additional payload to handle
type Action<P> = P extends void
? { type: ActionType<P> }
: { type: ActionType<P>, payload: P }
*/
type Handler<S, P> = P extends void
? (state: S) => S
: (state: S, payload: P) => S
interface ActionHandler<S, P> {
actionType: ActionType<P>
handler: Handler<S, P>
}
declare function handler<S, P>(actionType: ActionType<P>, handler: Handler<S, P>): ActionHandler<S, P>
declare function createReducer<S>(
defaultState: S,
...actionHandlers: ActionHandler<S /* force state S for every action handler*/, any>[]
): any
interface AppState {
dummy: string
}
const defaultState: AppState = {
dummy: ''
}
const NON_VOID_ACTION: ActionType<number> = 'NON_VOID_ACTION'
, VOID_ACTION: ActionType<void> = 'VOID_ACTION'
handler<AppState, number>(NON_VOID_ACTION, (state, _payload) => state), // ok - state is AppState
handler<AppState, void>(VOID_ACTION, state => state) // ok - state is AppState
createReducer(
defaultState,
handler(NON_VOID_ACTION, (state, _payload) => state), // ok - state is AppState
handler(VOID_ACTION, state => state) // unexpected - state is any
)
Expected behavior:
state parameter is infered to be "AppState" in the expression at the end
handler(VOID_ACTION, state => state)
Actual behavior:
state parameter is infered to be "any"
Playground Link:
Playground
(use noImplicitAny flag)
Related Issues:
Not sure #25301
Workaround:
When Handler is defined as follows
type Handler<S, P> = (state: S, payload: P) => S
it still allows to pass single argument handler and state is infered to be AppState