[英]Typescript: infer payload type and pass it to callback
这是键入Redux存储的简化示例。
interface SetNamePayload { name: string; }
export interface Action<TPayload extends object> {
type: string;
data: TPayload;
}
type SetNameAction = Action<SetNamePayload>;
// derive payload type from action type
type ResolveActionPayload<A extends Action<any>> =
A extends Action<infer P> ? P : never;
// return type should be resolved to SetNamePayload
function getPayload<T extends SetNameAction>(x: T): ResolveActionPayload<T>
{
// TS2322: Type 'SetNamePayload' is not assignable to
// type 'ResolveActionPayload<T>'.
return x.data;
}
为什么返回类型不能解析为SetNamePayload
,或者可以以其他方式确定这样声明的操作有效负载的类型?
似乎getPayload
上的泛型getPayload
是错误的,因为ResolveActionPayload
可以按预期工作:
当然,实际代码中还有很多动作类型。 该函数实际上看起来更像getPayload<T extends SomeAction | OtherAction | ...>
getPayload<T extends SomeAction | OtherAction | ...>
getPayload<T extends SomeAction | OtherAction | ...>
。 这确实是问题的MWE。
另外,我知道我可以反转类型并将有效负载类型用作通用参数,例如getPayload<T>(x: Action<T>): T
,这可能会更简单,更好地工作。 但是,这种类型的输入在代码库中得到了广泛的应用,这并不是我的全部,它需要大量重构,我想避免这种重构。
虽然条件类型似乎等同于动作类型脚本的data
属性的类型,但无法弄清楚。 如果条件类型包含未解析的类型参数,则通常不会扩展它们。 尽管在很多情况下这样做是有意义的,但这些情况非常专业,通常不会在编译器中实现。
在这种情况下,将类型表示为类型查询会更容易。 对于编译器来说,这很容易找出与x.data
相同的类型。 这有效
function getPayload<T extends SetNameAction>(x: T): SetNameAction['data']
{
return x.data;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.