这是键入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
上的泛型似乎是错误的,因为ResolveActionPayload
可以按预期工作:
在实际代码中,当然还有更多的操作类型。该函数实际上看起来更像getPayload<T extends SomeAction | OtherAction | ...>
。这确实是问题的MWE。
此外,我知道我可以反转类型并将有效负载类型用作通用参数,例如getPayload<T>(x: Action<T>): T
,这可能会更简单,更好地工作。但是,这种类型的代码已在代码库中广泛使用,这并不是我所有的代码,它需要大量重构,我想避免这种情况。
答案 0 :(得分:0)
虽然条件类型似乎等同于动作类型脚本的data
属性的类型,但无法弄清楚。如果条件类型包含未解析的类型参数,则通常不会扩展它们。尽管在很多情况下,这样做是有意义的,但这些情况非常专业,通常不会在编译器中实现。
在这种情况下,将类型表示为类型查询会更容易。对于编译器来说,这很容易找出与x.data
相同的类型。可行
function getPayload<T extends SetNameAction>(x: T): SetNameAction['data']
{
return x.data;
}