简体   繁体   English

推断 typescript 通用包装器 function 返回类型属性值

[英]Infer typescript generic wrapper function return type property value

How to properly infer xxx type to data ?如何正确推断dataxxx类型?

Restrictions:限制:

  • wrapper argument should accept only Promise<{ xxx: Data; }>包装参数应该只接受Promise<{ xxx: Data; }> Promise<{ xxx: Data; }> - currently works. Promise<{ xxx: Data; }> - 目前有效。
  • only wrapper can be changed只能更改包装器

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 aD直接相关的类型。 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}> .相反,我们说aPromise<{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.看起来挺好的。

Playground link to code 游乐场代码链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM