TypeScript 函数类型推导问题

我写了一个公共方法, 参数是一个返回值类型为Promise的方法。

export function apiWrapper(fn) {
    let id = 1;
    return async (params) => {
        id++;
        const _id = id;
        const res = await fn(params);
        if (_id === id) {
            return res;
        } else {
            throw new Error();
        }
    };
}

现在想给这个公共方法加上根据入参的类型推导,但是不会写了
比如:

const func = (name: string) => new Promise<string>((resolve) => resolve(name))

const func2 = apiWrapper(func)

// 如何得到func2的类型也为 (name: string) => Promise<string>
阅读 2.9k
2 个回答

参数 fn 的类型会给你传入参数的类型,如果足够精确的话,可以直接声明为精确类型:

export function apiWrapper(fn: (name: string) => Promise<string>) {
    return async (name: string) => await fn(name);
}

不过既然题主拿出来问,我猜应该是想兼容多一些类型,比如所有类型

export function apiWrapper<
    T extends (...args: any) => any,
    R = ReturnType<T>
>(fn: T): (...args: Parameters<T>) => R extends Promise<any> ? R : Promise<R> {
    const fnInner = async (...args: any): Promise<R> => await fn(...args);
    return <any>fnInner;
}

这里很尴尬的是我们知道 Rfn 的返回类型,也知道最终返回的一定是一个 Promise,但是 TypeScript 推导不出来,因为它通过声明的类型 T(现在并不知道实际传入的参数类型)来推导,而声明的类型 T 的返回值是 any。所以最后用 <any> 去掉类型约束检查来导出 …… 那么 apiWrapper 内部的逻辑就需要人工更仔细的检查了。不过这样 apiWrapper 封装出来的函数类型符合预期:

image.png

function apiWrapper<T = unknown, P = unknown>(fn: (_: P) => Promise<T>) {
    // 略
    return async (params: P) => {
        // 略
    };
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题