我试图从这里键入 annoate 一个版本的reflect
promise 方法 - https://stackoverflow.com/a/31424853/1828637
function reflectPromise(p){
return p.then(data => ({
data,
resolved: true
}))
.catch(error => ({
error,
rejected: true
}));
}
它所做的是接受一个承诺,并在解决或拒绝时返回另一个承诺。
我尝试用伪代码做的事情:
- 声明
data
typeof ResolveValue(p)
- 声明
error
是typeof RejectValue(p)
- 声明其他人可以测试
const didReject = !!(await (reflectedPromise(somePromise)).rejected
(这将对已解决的承诺做什么,返回{ data: xxx, resolved:true }
(是undefined
变成true
。目前,当我做!!blah.rejected
TypeScript 对我说Property 'rejected' does not exist on type
这是我到目前为止所拥有的:
function reflectPromise(p: Promise<any>): Promise<
{ data: any, resolved: boolean, rejected: void } |
{ error: any, resolved: void, rejected: boolean }
> {
return p.then(data: any) => ({
data,
resolved: true
}))
.catch((error: any) => ({
error,
rejected: true
}));
}
需要使用泛型类型来推断结果的类型。错误的类型在 Typescript 中被认为是any
的,并且那里没有类型安全性。此外,我会键入rejected
并resolved
undefined
而不是void
(它们的值毕竟在运行时是未定义的,因此它更准确(,当它们不存在时,我会将它们设为可选。
此外,当resolve
和reject
true
时,我会将它们键入为布尔文字类型true
,以使类型保护更好地工作。
把它放在一起,编译(有严格的空检查(:
function reflectPromise<T>(p: Promise<T>): Promise<
{ data: T, resolved: boolean, rejected?: undefined } |
{ error: any, resolved?: undefined, rejected: boolean }
> {
return p.then((data: any) => ({
data,
resolved: true
}))
.catch((error: any) => ({
error,
rejected: true
}));
}
(async function (somePromise: Promise<number>) {
const result = await (reflectPromise(somePromise));
const didReject = !!result.rejected
if (result.rejected) {
result.error // result is { error: any, resolved?: undefined, rejected: true }
} else {
result.data // result { data: number, resolved: true, rejected?: undefined }
}
if (result.resolved) {
result.data // result { data: number, resolved: true, rejected?: undefined }
} else {
result.error // result is { error: any, resolved?: undefined, rejected: true }
}
})(Promise.resolve(1));
在我看来,reflectPromise
的实现看起来更好async/await
:
async function reflectPromise<T>(p: Promise<T>): Promise<
{ data: T, resolved: true, rejected?: undefined } |
{ error: any, resolved?: undefined, rejected: true }
> {
try {
return {
data: await p,
resolved: true
}
} catch (e) {
return {
error: e,
rejected: true
}
}
}
如果没有严格的 null 检查,如果我们需要稍微更改类型,并在两个分支上设置resolved
和reject
,类型保护将部分工作:
async function reflectPromise<T>(p: Promise<T>): Promise<
{ data: T, resolved: true, rejected: false } |
{ error: any, resolved: false, rejected: true }
> {
try {
return {
data: await p,
resolved: true,
rejected: false,
}
} catch (e) {
return {
error: e,
rejected: true,
resolved: false
}
}
}
(async function (somePromise: Promise<number>) {
const result = await (reflectPromise(somePromise));
const didReject = !!result.rejected
if (result.rejected) {
result.error // result is { error: any, resolved?: undefined, rejected: true }
}
if (result.resolved) {
result.data // result { data: number, resolved: true, rejected?: undefined }
}
})(Promise.resolve(1));