'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 |