我有两个请求类型 AddInterestAreaRequest
和 RemoveInterestAreaRequest
。我想创建一个可以传入 action
的实用程序类型,它会返回 params
。
这是我所拥有的
type AddInterestAreaRequest = {
action: 'addInterestArea';
params: AddInterestAreaParams;
};
type RemoveInterestAreaRequest = {
action: 'removeInterestArea';
params: RemoveInterestAreaParams;
};
export type JSBRequest = {
configs?: BridgeRequestConfigs;
} & (AddInterestAreaRequest | RemoveInterestAreaRequest);
type GetParamByAction<T extends JSBRequest['action']> =
JSBRequest['action'] extends T ? never : JSBRequest['params'];
type Testing = GetParamByAction<'addInterestArea'>;
我所拥有的不起作用,Testing
是 AddInterestAreaParams | RemoveInterestAreaParams
因为 JSBRequest['params']
始终是 AddInterestAreaParams | RemoveInterestAreaParams
而且我基本上想让Testing
成为唯一的AddInterestAreaParams
知道如何实现它吗?
谢谢。
答案 0 :(得分:2)
您可以使用 discriminated union 在类型级别区分 the Extract<T, U>
utility type,它过滤联合类型 T
并只保留那些可分配给 U
的成员:
type GetParamByAction<T extends JSBRequest['action']> =
Extract<JSBRequest, { action: T }>["params"]
因此 Extract<JSBRequest, {action: T}>
将仅返回 JSBRequest
的 action
属性可分配给 T
的那些成员,这应该正是您想要的。然后我们index进入它以获取它的 params
属性。
让我们确保它有效:
type Testing = GetParamByAction<'addInterestArea'>;
// type Testing = AddInterestAreaParams
看起来不错。
答案 1 :(得分:0)
type GetParamByAction<T extends JSBRequest['action']> =
T extends 'addInterestArea' ? AddInterestAreaRequest['params'] : RemoveInterestAreaRequest['params'];
type Testing = GetParamByAction<'addInterestArea'>; // Should be AddInterestAreaParams
答案 2 :(得分:0)
在这种情况下,我建议先使用 TS 帮助程序 Extract 从联合中提取类型:
type GetJSBRequestByAction<T extends JSBRequest['action']> = Extract<JSBRequest, { action: T }>;
type Test1 = GetJSBRequestByAction<'addInterestArea'>;
// This gives:
// {
// configs?: BridgeRequestConfigs;
// } & AddInterestAreaRequest
然后你就可以访问参数了:
type GetParamByAction<T extends JSBRequest['action']> = GetJSBRequestByAction<T>['params'];