类型注释reflectPromise方法

时间:2018-09-19 21:29:51

标签: typescript

我试图从此处键入对reflect Promise方法的版本进行注解-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(这对于已解决的Promise会做什么,返回{ data: xxx, resolved:true })是将undefined变成true。目前,当我!!blah.rejected打字时对我说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
             }));
}

1 个答案:

答案 0 :(得分:2)

您需要使用泛型来推断结果的类型。错误的类型在Typescript中被视为any,并且那里没有类型安全性。同样,我会以rejected而不是resolved的形式输入undefinedvoid(它们的值毕竟在运行时是不确定的,因此更准确),当它们出现时,我会使其成为可选项不存在。

另外,当resolverejecttrue时,我将它们键入为布尔文字类型true,以使类型保护更好地工作。

将其放在一起,将进行编译(使用严格的null检查):

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