我正在调用下面的函数,返回Promise<boolean>

const fnc = (i:number) : Promise<boolean>  => Promise.resolve(true)

// Promise<boolean>
const res1 = errorHandler(errorPredicates.sdkError1, fnc, null, 4);

然而,当我用另一个错误处理程序嵌套它时,返回的对象变为Promise<any>

// Promise<any>
const res2 = errorHandler(errorPredicates.sdkError1, errorHandler, null, errorPredicates.sdkError2, fnc, null, 4);

下面是复制问题的typescript代码示例.我不确定这里出了什么问题,也不确定这是否是typescript的限制.我如何解决这个打字问题?

type PromiseFn = (...args: any[]) => Promise<any>;
type UnwrappedReturnType<T extends PromiseFn> = T extends (...args: any) => Promise<infer R> ? R : any

type ThrottlerPredicate = (err: any) => boolean;

type ThrottlerPredicates = {
    sdkError1: ThrottlerPredicate
    sdkError2: ThrottlerPredicate
}

const errorPredicates: ThrottlerPredicates = {
    sdkError1: (err) => err?.message?.search(`429:`) != -1,
    sdkError2: (err) => err?.message?.search(`Request was throttled.`) != -1
}

async function errorHandler<ApiFn extends PromiseFn>(
    predicate: ThrottlerPredicate,
    promiseFunction: ApiFn,
    thisArg: ThisParameterType<ApiFn>,
    ...args: Parameters<ApiFn>
): Promise<UnwrappedReturnType<ApiFn>> {
    let errCount = 0
    do {
        try {
            const promiseResult = await promiseFunction.call(thisArg, ...args)
            return promiseResult
        } catch (err: any) {
            //console.error(err)
            if (predicate(err)) {
                if (errCount < 20)
                    ++errCount;
                var ms = 1500 * errCount
            } else
                throw (err);
        }
    }
    while (true);
}

const fnc = (i:number) : Promise<boolean>  => Promise.resolve(true)

// Promise<boolean>
const res1 = errorHandler(errorPredicates.sdkError1, fnc, null, 4);

// Promise<any>
const res2 = errorHandler(errorPredicates.sdkError1, errorHandler, null, errorPredicates.sdkError2, fnc, null, 4);



推荐答案

返回类型为Promise<any>的原因是,TypeScript的泛型基于输入的参数预期该类型.因此,res2PromiseFunction的返回类型是Promise<UnwrappedReturnType<ApiFn>.UnwrappedReturnType类型需要PromiseFn类型的返回值.此时,ApiFn类型是PromiseFn的扩展,PromiseFn类型的返回值是Promise<any>,因此UnwrappedReturnType<ApiFn>类型是any.

换句话说,如果指定ApiFn泛型类型,则可以进行res2类型推断.

...
type ErrorHandler<ApiFn extends PromiseFn> = (
  predicate: ThrottlerPredicate,
  promiseFunction: ApiFn,
  thisArg: ThisParameterType<ApiFn>,
  ...args: Parameters<ApiFn>
) => Promise<UnwrappedReturnType<ApiFn>>;

// Promise<boolean>
const res2 = errorHandler(errorPredicates.sdkError1, errorHandler as ErrorHandler<typeof fnc>, null, errorPredicates.sdkError2, fnc, null, 4);

不幸的是,我不明白你想要的功能,所以我根据你的问题回答.如果你能向我解释一下逻辑,我会想出更好的办法.

Javascript相关问答推荐

当我使用jQuery时,我的图标显示为[对象对象]

有没有方法在Angular中的bowser选项卡之间移动HTML?

vue3类型脚本中可能未定义对象''

更新Reduxstore 中的状态变量,导致整个应用程序出现不必要的重新渲染

我的YouTube视频没有以html形式显示,以获取免费加密信号

使用CDO时如何将Vue组件存储在html之外?

React存档iframe点击行为

确定MutationRecord中removedNodes的索引

如何避免移动设备中出现虚假调整大小事件?

Phaser框架-将子对象附加到Actor

按钮未放置在html dis位置

警告!合同执行期间遇到错误[执行已恢复](Base Layer 2)

仅针对RTK查询中的未经授权的错误取消maxRetries

处理时间和字符串时MySQL表中显示的日期无效

ChartJs未呈现

当id匹配时对属性值求和并使用JavaScript返回结果

在使用REACT更改了CSS类之后,无法更改CSS样式

try 使用PM2在AWS ubuntu服务器上运行 node 进程时出错

在GraphQL解析器中修改上下文值

有没有办法通过使用不同数组中的值进行排序