I've got two subtypes in our application:
export interface QueuedAction extends Action {
meta: {
queueName: string;
overwrite: boolean;
}
}
export interface BroadcastAction extends Action {
meta: {
channelName: string;
}
}
And based on typescript interface require one of two properties to exist I union them like so:
export type MetaAction = QueuedAction | BroadcastAction;
That's great and all, but I sometimes need to act on a MetaAction
where one half of the inclusive union is guaranteed.
This has issues:
const wrapBroadcast = (action: AnyAction, channelName = 'DEFAULT_CHANNEL'): MetaAction => ({
...action,
meta: { ...action.meta, channelName },
});
const unwrapBroadcast = (action: MetaAction) => {
if (!action.meta) return action;
const { channelName, ...rest } = action.meta; // channelName does not exist on type '{ queueName: string, overwrite?: boolean} | { channelName: string }'
const unwrappedAction = { ...action, meta: rest };
return unwrappedAction;
}
And if I switch it from MetaAction
to BroadcastAction | {BroadcastAction & MetaAction}
(to say, it's always going to have channelName
but the rest of meta is flexible). I get this error when I go to use it:
Argument of type 'MetaAction' is not assignable to parameter of type 'BroadcastAction & MetaAction'
Until I swap the return type of wrapAction
to match.
Is there a more generic way to declare BroadcastAction | {BroadcastAction & MetaAction}
given in the future we may end up with more stuff in 'meta' and we'd need this pattern elsewhere?