I have a type definition for a function. I'm defining the type of the second argument as conditional on the type of the first argument, like so:
const FOO = "FOO";
const BAR = "BAR";
let fooPayload = {
zip: "zap"
}
let barPayload = {
cat: "dog"
}
type ActionTypes = typeof FOO | typeof BAR;
interface MyFunction<T extends ActionTypes = ActionTypes> {
(
action: {
type: T;
payload: T extends typeof FOO
? typeof fooPayload
: typeof barPayload;
}
): boolean;
}
The function that MyFunction interface refers to has a switch statement within it that switches based on action.type and, depending on the case, does something with action.payload. Here's an example:
const myFunction:MyFunction = (action) => {
switch (action.type) {
case FOO:
action.payload.zip = "new zap"
return true
case BAR:
action.payload.cat = "new dog"
return false
default:
return false
}
}
The issue I'm having is that Typescript isn't correctly inferring what action.payload should be from the switch statement. For example, if action.type is equal to "FOO" then it should infer that action.payload MUST be typeof fooPayload. Instead, it infers that it is typeof fooPayload | typeof barPayload.
This doesn't make any sense as the type definition for action.payload is based on the value of action.type, and since action.payload.zip is being called within a switch statement that can only occur when action.type equals "FOO", it should infer that the only possible type for action.payload is typeof fooPayload.
What am I doing wrong here?