Typescript 嵌套函数包装 Return 类型问题

Typescript nested function wrapping Return type problem

我正在调用下面的函数 returns 我 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);

下面是重现该问题的示例打字稿代码。我不确定这里有什么问题,或者它是否是打字稿的限制。我该如何解决这个打字问题?

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



之所以return类型是Promise<any>是因为Typecript的泛型需要基于输入参数的类型。因此,res2PromiseFunction的return类型为Promise<UnwrappedReturnType<ApiFn>UnwrappedReturnType 类型需要 PromiseFn 类型的 return 值。此时ApiFn类型是PromiseFn的extends,而PromiseFn类型的return值是Promise<any>,所以UnwrappedReturnType<ApiFn>类型是 any。 同样,用作参数的 errorHandler 泛型 ApiFn 类型与 PromiseFn((...args: any[]) => Promise) 类型相同,因为有没有预期的参数。

换句话说,如果您指定 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);

很遗憾,我没有理解你想要的功能,所以我根据你的问题进行了回答。如果你能给我解释一下逻辑,我会考虑更好的方法。