Tengo una función que toma una función asíncrona arbitraria y devuelve el resultado de esperar esa función asíncrona, pero envuelta en un intento/captura que agrega algo de lógica adicional. Ver ts patio de recreo .
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) ); Siento que // @ts-expect-error en with401Redirection no debería ser necesario. ¿Cómo puedo eliminarlo o, en general, limpiar el tipeo de la función with401Redirection ? Tenga en cuenta que quiero mantener el hecho de que las funciones getUser y saveItem tienen sus tipos deducidos automáticamente para mí.
Prueba esto:
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; } }; }Lea sobre el próximo tipo
Awaitedactual en TS 4.5: