如何正确推断xxx型到data型?

限制:

  • 包装器参数应该只接受Promise<{ xxx: Data; }>-当前有效.
  • 只能更改包装器

Typescript sandbox

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?
})

推荐答案

你可能期望编译器将A推断为Promise<{ xxx: string }>,并由此推断Datastring,因为A extends Promise<{xxx: Data}>.不幸的是,在TypeScript中,像extends Promise<{xxx: Data}>这样的generic constraints不能作为类型参数的推理站点.(这种行为在microsoft/TypeScript#7234年被提出,但从未实施.)因此,编译器不知道将Data推断为什么,因此返回到the unknown type.哎呀.

为了从a中推断出Data(我将其重命名为D,以便更符合类型参数的常用命名约定),需要给a一个与D直接相关的类型.以下是最简单的方法:

function wrapper<D>(a: Promise<{xxx: D}>): Promise<{ data: D }> {
    return 1 as any
}

你的代码中没有真正使用A,所以我忽略了它.相反,我们说a属于Promise<{xxx: D}>型.编译器can通过匹配Promise<{xxx: string}>Promise<{xxx: D}>,由此推断D.

让我们看看它的实际行动:

wrapper(a()).then(res => {
    const data: string = res.data // okay
});

看起来不错.

Playground link to code

Typescript相关问答推荐

从传递的数组中出现的值设置返回键的类型

如何根据数据类型动态注入组件?

如何在ts中使用函数重载推断参数类型

当类型断言函数返回假时,TypScript正在推断从不类型

TypScript手册中的never[]参数类型是什么意思?

typescribe不能使用值来索引对象类型,该对象类型满足具有该值的另一个类型'

异步动态生成Playwright测试,显示未找到测试

有没有办法解决这个问题,类型和IntrinsicAttributes类型没有相同的属性?

如何使用一个字段输入对象,其中每个键只能是数组中对象的id属性,而数组是另一个字段?

如何解决类型T不能用于索引类型{ A:typeof A; B:typeof B;. }'

通过按键数组拾取对象的关键点

在对象中将缺省值设置为空值

如何在NX工作区项目.json中设置类似angular.json的两个项目构建配置?

如何将v-for中的迭代器编写为v-if中的字符串?

如何在不违反挂钩规则的情况下动态更改显示内容(带有状态)?

棱角分明-什么是...接口类型<;T>;扩展函数{new(...args:any[]):t;}...卑鄙?

如何以类型安全的方式指定键的常量列表,并从该列表派生所挑选的接口?

React中的效果挂钩在依赖项更新后不会重新执行

两个接口的TypeScript并集,其中一个是可选的

在Typescript 无法正常工作的 Three.js 中更新动画中的 GLSL 统一变量