包装异步函数的函数的 TypeScript 类型定义
TypeScript type definition for function that wraps async function
我有一个函数采用任意异步函数和 returns 等待该异步函数的结果,但包装在 try/catch 中,它添加了一些额外的逻辑。参见 ts playground。
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)
);
我觉得 with401Redirection
中的 // @ts-expect-error
不应该是必需的——我怎样才能删除它或一般清理 with401Redirection
函数的输入?请记住,我想保持这样一个事实,即 getUser
和 saveItem
函数会自动为我推断它们的类型。
试试这个:
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:
我有一个函数采用任意异步函数和 returns 等待该异步函数的结果,但包装在 try/catch 中,它添加了一些额外的逻辑。参见 ts playground。
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)
);
我觉得 with401Redirection
中的 // @ts-expect-error
不应该是必需的——我怎样才能删除它或一般清理 with401Redirection
函数的输入?请记住,我想保持这样一个事实,即 getUser
和 saveItem
函数会自动为我推断它们的类型。
试试这个:
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: