[英]Infer typescript generic wrapper function return type property value
How to properly infer xxx
type to data
?如何正确推断data
的xxx
类型?
Restrictions:限制:
Promise<{ xxx: Data; }>
包装参数应该只接受Promise<{ xxx: Data; }>
Promise<{ xxx: Data; }>
- currently works. Promise<{ xxx: Data; }>
- 目前有效。Typescript sandbox Typescript沙箱
function wrapper<
Data,
A extends Promise<{ xxx: Data; }>,
>(a: A): Promise<{ data: Data }> {
return 1 as any
}
async function a(): Promise<{ xxx: string }> {
return { xxx: 'a' }
}
wrapper(a()).then(res => {
const data: string = res.data // is unknown, how to make it infer string?
})
Presumably you expect the compiler to infer A
as Promise<{ xxx: string }>
, and from there to infer Data
as string
because A extends Promise<{xxx: Data}>
.大概您希望编译器将A
推断为Promise<{ xxx: string }>
,并从那里将Data
推断为string
,因为A extends Promise<{xxx: Data}>
。 Unfortunately, in TypeScript, generic constraints like extends Promise<{xxx: Data}>
don't serve as inference sites for type parameters.不幸的是,在 TypeScript 中,像extends Promise<{xxx: Data}>
这样的通用约束不能作为类型参数的推理站点。 (Such behavior was suggested in microsoft/TypeScript#7234 but was never implemented.) So the compiler has no idea what to infer Data
as, and thus it falls back to the unknown
type . (此类行为在microsoft/TypeScript#7234中提出,但从未实现。)因此编译器不知道将Data
推断为什么,因此它会回退到unknown
类型。 Oops.哎呀。
In order to get inference for Data
(which I will rename to D
to be more in keeping with the usual naming conventions for type parameters) from a
, you'll need to give a
a type which is directly related to D
.为了从 a 获得对Data
的推断(我将其重命名为D
以更符合类型参数的通常命名约定),您需要给a
a
与D
直接相关的类型。 Here's the easiest way to do it:这是最简单的方法:
function wrapper<D>(a: Promise<{xxx: D}>): Promise<{ data: D }> {
return 1 as any
}
You weren't really using A
in your code, so I left it out.您并没有真正在代码中使用A
,所以我将其遗漏了。 Instead, we say that a
is of type Promise<{xxx: D}>
.相反,我们说a
是Promise<{xxx: D}>
类型。 The compiler can infer D
from that, by matching Promise<{xxx: string}>
to Promise<{xxx: D}>
.编译器可以通过将Promise<{xxx: string}>
匹配到Promise<{xxx: D}>
来推断D
Let's see it in action:让我们看看它的实际效果:
wrapper(a()).then(res => {
const data: string = res.data // okay
});
Looks good.看起来挺好的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.