javascript - 将条件类型映射回联合类型?
问题描述
我正在尝试执行以下操作(也可以在 TypeScript Playground 上查看),但是函数的返回类型出现错误,告诉我条件类型不能分配给联合:
type RequestType =
| 'foo'
| 'bar'
| 'baz'
interface SomeRequest {
id: string
type: RequestType
sessionId: string
bucket: string
params: Array<any>
}
type ResponseResult = string | number | boolean
async function sendWorkRequest<T extends RequestType>(
type: T,
...params
): Promise<
T extends 'foo'
? string
: T extends 'bar'
? number
: T extends 'baz' ? boolean : never
> {
await this.readyDeferred.promise
const request: SomeRequest = {
id: 'abc',
bucket: 'bucket',
type,
sessionId: 'some session id',
params: [1,'two',3],
}
const p = new Promise<ResponseResult>((/*...*/) => {/*...*/})
this.requests[request.id] = p
this.worker.postMessage(request)
return p // <-------------------------------- ERROR
}
基本上,我希望条件类型产生其中一种ResponseResult
类型。因此,根据type
传递给函数的参数,它应该返回ResponseResult
联合中的一种类型(作为 Promise)。
我怎样才能使它工作,以便type
参数的类型确定返回的 Promise 的类型?
这是另一种没有条件类型的方法,但我想知道是否可以使用type
arg 的条件类型来完成。
编辑:根据 Erik 在下面的回答,我也很好奇为什么这个不起作用,以及是否可以在不重新定义ResponseResult
和不更改函数返回类型的情况下使其工作。
@Erik,第二个例子。
解决方案
您需要将 Type 封装为(假设)打字稿不能假设(计算)两个非引用条件类型是相同的。
所以改为
type ResponseResult<T> =
T extends 'foo'
? string
: T extends 'bar'
? number
: T extends 'baz' ? boolean : never;
现在您可以将函数的签名更改为:
async function sendWorkRequest<T extends RequestType>(
type: T,
...params
): Promise<ResponseResult<T>> {
并更新p
:
const p = new Promise<ResponseResult<T>>(() => { });
你知道为什么或如何在不改变返回类型和不修改返回类型定义的情况下这样做吗?
不,因为 aConditional Type
不等于 a Type
。
那是否需要在调用函数的地方进行显式类型转换?
不,我可以使用 type 属性来模拟 Promise 并查看它是否属于该类型:
有没有办法让它安全(没有类型转换)?
不必要
推荐阅读
- apache-spark - 是否可以更改 Great_Expectations 数据文档中显示的 Great Expectations 徽标
- c++ - 在 C++ 代码中使用“模板”关键字作为某个对象的属性是什么意思?
- javascript - Wordpress 网格/列表切换:如何添加和删除类 js
- ktor - “序言中不能有内容。” IntelliJ Ultimate
- openssl - 尝试使用 openssl 解密文件时突然出现问题
- excel - 如何使用 VBA Excel 在按钮单击事件上从另一个工作表中对整个工作表进行排序
- javascript - Shopify 脚本标签:未捕获的类型错误:$ 不是函数
- pandas - 在 pandas 和 scipy.signal 中查找局部最大值/最小值的索引
- ruby-on-rails - 编辑和更新用户信息。在 RoR
- python - 删除命令消息 -Python -discord.py