简体   繁体   English

包装异步函数的函数的 TypeScript 类型定义

[英]TypeScript type definition for function that wraps async function

I have a function takes takes an arbitrary async function and returns the result of awaiting that async function, but wrapped in a try/catch which adds some additional logic.我有一个函数需要一个任意的异步函数并返回等待该异步函数的结果,但包装在一个 try/catch 中,它增加了一些额外的逻辑。 See ts playground .ts 操场

const with401Redirection =
    <T extends (...args: any[]) => Promise<any>>(
        call: T
    ): ((...args: Parameters<T>) => ReturnType<T>) =>
    // @ts-expect-error
    async (...args: Parameters<T>): ReturnType<T> => {
        try {
            return await call(...args);
        } catch (error) {
            if ((error as any).httpStatus === 401) {
                // do some stuff here
            }

            throw error;
        }
    };

interface User {
    id: string;
    name: string;
}

interface ItemPayload {
    field1: string;
    field2: string;
}

interface ItemResponse {
    id: string;
    field1: string;
    field2: string;
}

const client = {
    get<ResponseType>(url: string): Promise<ResponseType> {
        // logic to hit server and return result here
        return '' as any;
    },
    post<ResponseType>(url: string, body: Record<string, any>): Promise<ResponseType> {
        // logic to hit server and return result here
        return '' as any;
    }
};

const getUser = with401Redirection(() =>
    client.get<User>('url_1')
);

const saveItem = with401Redirection((body: ItemPayload) =>
    client.post<ItemResponse>('url_2', body)
);

I feel like the // @ts-expect-error in with401Redirection shouldn't be necessary -- how can I remove it or generally clean up the typing of the with401Redirection function?我觉得with401Redirection// @ts-expect-error with401Redirection应该是必要的——我该如何删除它或通常清理with401Redirection函数的类型? Keep in mind I want to maintain the fact that the getUser and saveItem functions have their types automatically inferred for me.请记住,我想保持这样一个事实,即getUsersaveItem函数会自动为我推断它们的类型。

Try this:尝试这个:

TS Playground link TS 游乐场链接

type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T;
type AsyncFn = (...args: any[]) => Promise<any>;

function with401Redirection <T extends AsyncFn>(call: T): (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>> {
    return async (...args: Parameters<T>) => {
        try {
            return await call(...args);
        }
        catch (exception) {
            if (typeof exception === 'object' && (exception as any)?.httpStatus === 401) {
                // do some stuff here
            }
            throw exception;
        }
    };
}

Read about the actual, upcoming Awaited type in TS 4.5:阅读 TS 4.5 中实际的、即将推出的Awaited类型:

https://devblogs.microsoft.com/typescript/announcing-typescript-4-5-beta/#the-awaited-type-and-promise-improvements https://devblogs.microsoft.com/typescript/annoucing-typescript-4-5-beta/#the-awaited-type-and-promise-improvements

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM