'How to omit an union type depending on field value
I have this type (come from third party library):
type StackActionType = {
    type: 'REPLACE';
    payload: {
        name: string;
        key?: string | undefined;
        params?: object;
    };
    source?: string;
    target?: string;
} | {
    type: 'PUSH';
    payload: {
        name: string;
        params?: object;
    };
    source?: string;
    target?: string;
} | {
    type: 'POP';
    payload: {
        count: number;
    };
    source?: string;
    target?: string;
} | {
    type: 'POP_TO_TOP';
    source?: string;
    target?: string;
};
I would like to infer remaining union types. I can achieve that with field key/name. ex:
const action: StackActionType = ...;
if("payload" in action) {
  // action is infered with union types of: 'REPLACE', 'PUSH', 'POP' (contains "payload" field) and 'POP_TO_TOP' is omited 
}
But there is a way to achieve that using field value instead of field name, ex:
if(["PUSH", "REPLACE"].includes(action.type)) {
 // action should only infer union of 'REPLACE' & 'PUSH'. But this is not working...
} 
Any idea (without copying/alter original type) ?
EDIT:
Here is a try with type guard & if: Typscript sandbox
Solution 1:[1]
I believe your solution will work if you instead use:
if (action.type == 'PUSH' || action.type == 'REPLACE') {}
Typescript cannot statically analyze the type possibilities when you use [].includes since an array can technically contain dynamic (runtime) values.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | Josh Bothun | 
