[英]Typescript type inference for function parameter's return type
in my react project I declare my api requests with this pattern:在我的反应项目中,我用这种模式声明了我的 api 请求:
export type LoginApiResponse = {
token: string,
user: User
}
export function login(email: string, password: string): Promise<LoginApiResponse> {
return AuthService.signinWithEmailAndPassword(email, password)
}
and I consume them through a custom hook我通过自定义钩子消耗它们
export function useApi<T, Fn extends (...args: any[]) => Promise<T>>(
fn: Fn
) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState();
const execute = async (...params: Parameters<Fn>) => {
setLoading(true);
try {
const result = await fn(...params);
setLoading(false);
return result;
} catch (err) {
console.warn("sideEfect execution error", err, JSON.stringify(err));
setError(err);
setLoading(false);
throw (error);
}
};
return { loading, execute, error };
}
with an implementation like this像这样的实现
const loginExecutor = useApi<LoginApiResponse, typeof api.login>(api.login) const loginExecutor = useApi<LoginApiResponse, typeof api.login>(api.login)
In this way I encapsulate loading and error state for a given api request, plus I have full typing support通过这种方式,我封装了给定 api 请求的加载和错误状态,而且我有完整的打字支持
THE QUESTION问题
Now my question is: is there a way to take advantage of typescript type inference to infer the return type and parameters type of the fn function in order to be able to write现在我的问题是:有没有办法利用 typescript 类型推断来推断 fn 函数的返回类型和参数类型,以便能够编写
useApi(api.login)
instead of代替
useApi<LoginApiResponse, typeof api.login>(api.login)
While keeping the same strong typing?同时保持相同的强类型?
I see that your example infers everything except a response.我看到您的示例推断出除响应之外的所有内容。 It has the following type:
它有以下类型:
const loginExecutor = useApi(login)
const loginExecutor: {
loading: boolean;
execute: (email: string, password: string) => Promise<unknown>;
error: string;
}
Try on TS Playground试玩TS Playground
I updated useApi
to extract args and return type separarly:我更新了
useApi
以分别提取 args 和返回类型:
export function useApi<A extends any[], T>(
fn: (...args: A) => Promise<T>
)
So now we get following type:所以现在我们得到以下类型:
const loginExecutor = useApi(login)
const loginExecutor: {
loading: boolean;
execute: (email: string, password: string) => Promise<LoginApiResponse>;
error: string;
}
Try on TS Playground试玩TS Playground
Please note that my examples were tested on TS >= 4.请注意,我的示例在 TS >= 4 上进行了测试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.