I have two types of objects save
and exit
and another one save-exit
which acts like both. The purpose is when I run the exec
function below in the case of the save-exit
object type both if blocks will be covered:
const save = Symbol('save');
const exit = Symbol('exit');
type Save = typeof save;
type Exit = typeof exit;
type SaveExit = Save & Exit;
type MenuRequestType = Save | Exit | SaveExit;
function exec(val: MenuRequestType) {
if (val === save) {
console.log('save')
}
if (val === exit) {
console.log('exit')
}
}
let a: MenuRequestType = /* new SaveExit(); */
exec(a) // prints both save and exit
I also tried to do this with enums but no progress so far. Any ideas how to adjust this so it works?
CodePudding user response:
Update in response to your comment:
const save = Symbol('save');
const exit = Symbol('exit');
const saveExit = Symbol('save-exit');
// You might not need these:
// type Save = typeof save;
// type Exit = typeof exit;
// type SaveExit = typeof saveExit;
const allActions = [save, exit, saveExit] as const; // readonly [typeof save, typeof exit, typeof saveExit]
type Action = typeof allActions[number]; // typeof save | typeof exit | typeof saveExit
const actionFunction: Record<Action, () => void> = {
[save] () {
console.log('save');
},
[exit] () {
console.log('exit');
},
[saveExit] () {
this[save]();
this[exit]();
},
};
function act (action: Action): void {
actionFunction[action]();
}
act(save) // "save"
act(exit) // "exit"
act(saveExit) // "save", "exit"
Original answer:
Just create a third type to represent both:
const save = Symbol('save');
const exit = Symbol('exit');
const saveExit = Symbol('save-exit');
// You might not need these:
// type Save = typeof save;
// type Exit = typeof exit;
// type SaveExit = typeof saveExit;
const allActions = [save, exit, saveExit] as const; // readonly [typeof save, typeof exit, typeof saveExit]
type Action = typeof allActions[number]; // typeof save | typeof exit | typeof saveExit
function act (action: Action): void {
switch (action) {
case save: {
console.log('save');
break;
}
case exit: {
console.log('exit');
break;
}
case saveExit: {
console.log('save');
console.log('exit');
break;
}
}
}
act(save) // "save"
act(exit) // "exit"
act(saveExit) // "save", "exit"
CodePudding user response:
Though not a perfect solution I'm actually looking for something like this:
const save = Symbol('save');
const exit = Symbol('exit');
const Save = { [save]: true };
const Exit = { [exit]: true };
const SaveExit = { [save]: true, [exit]: true };
type ActionType = typeof Save | typeof Exit | typeof SaveExit;
function exec(val: ActionType) {
if (save in val) {
console.log('save')
}
if (exit in val) {
console.log('exit')
}
}
let a: ActionType = SaveExit;
exec(a) // prints both save and exit
any other more elegant solutions/improvements are highly welcome!