类型注释反射承诺方法



我试图从这里键入 annoate 一个版本的reflectpromise 方法 - https://stackoverflow.com/a/31424853/1828637

function reflectPromise(p){
return p.then(data => ({
data,
resolved: true
}))
.catch(error => ({
error,
rejected: true
}));
}

它所做的是接受一个承诺,并在解决或拒绝时返回另一个承诺。

我尝试用伪代码做的事情:

  1. 声明datatypeof ResolveValue(p)
  2. 声明errortypeof RejectValue(p)
  3. 声明其他人可以测试const didReject = !!(await (reflectedPromise(somePromise)).rejected(这将对已解决的承诺做什么,返回{ data: xxx, resolved:true }(是undefined变成true。目前,当我做!!blah.rejectedTypeScript 对我说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的,并且那里没有类型安全性。此外,我会键入rejectedresolvedundefined而不是void(它们的值毕竟在运行时是未定义的,因此它更准确(,当它们不存在时,我会将它们设为可选。

此外,当resolverejecttrue时,我会将它们键入为布尔文字类型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 检查,如果我们需要稍微更改类型,并在两个分支上设置resolvedreject,类型保护将部分工作:

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));

最新更新