在我们的应用程序中有两个子类型:
export interface QueuedAction extends Action {
meta: {
queueName: string;
overwrite: boolean;
}
}
export interface BroadcastAction extends Action {
meta: {
channelName: string;
}
}
基于typescript interface require one of two properties to exist,我将它们合并如下:
export type MetaAction = QueuedAction | BroadcastAction;
这很好,但是有时候我需要对MetaAction
进行操作,其中包含联合的一半是有保证的。
这有以下问题:
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;
}
如果我把它从MetaAction
切换到BroadcastAction | {BroadcastAction & MetaAction}
(也就是说,它总是会有channelName
,但 meta的其余部分是灵活的),我得到这个错误,当我去使用它:
类型为“MetaAction”的参数不能赋给类型为“BroadcastAction & MetaAction”的参数
直到我交换wrapAction
的返回类型以匹配。
有没有一种更通用的方法来声明BroadcastAction | {BroadcastAction & MetaAction}
,如果将来我们可能会在“ meta”中使用更多的东西,并且我们在其他地方需要这个模式?
1条答案
按热度按时间n6lpvg4x1#
使MetaAction成为泛型
使这个模式更通用的简单方法是使它...通用:
也就是说,
MetaAction
接受一个 option 参数T
,该参数必须扩展任何带有{ meta: any }
或{}的内容。为了获得更高的类型安全性,请使特定的MetaAction扩展Base类型:
现在,您可以拥有具有或不具有所需子类型的MetaAction,只要该子类型扩展BaseMetaAction即可。
以下是你会使用和不会使用它的方式: