函数参数 return 类型的打字稿类型推断
Typescript type inference for function parameter's return type
在我的 React 项目中,我用这种模式声明了我的 api 请求:
export type LoginApiResponse = {
token: string,
user: User
}
export function login(email: string, password: string): Promise<LoginApiResponse> {
return AuthService.signinWithEmailAndPassword(email, password)
}
我通过自定义挂钩使用它们
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 };
}
像这样的实现
const loginExecutor = useApi(api.login)
通过这种方式,我封装了给定 api 请求的加载和错误状态,而且我有完整的输入支持
问题
现在我的问题是:有没有办法利用打字稿类型推断来推断 fn 函数的 return 类型和参数类型,以便能够编写
useApi(api.login)
而不是
useApi<LoginApiResponse, typeof api.login>(api.login)
同时保持相同的强类型?
我看到您的示例推断了除响应之外的所有内容。它具有以下类型:
const loginExecutor = useApi(login)
const loginExecutor: {
loading: boolean;
execute: (email: string, password: string) => Promise<unknown>;
error: string;
}
我更新了 useApi
以提取参数并 return 分别输入:
export function useApi<A extends any[], T>(
fn: (...args: A) => Promise<T>
)
所以现在我们得到以下类型:
const loginExecutor = useApi(login)
const loginExecutor: {
loading: boolean;
execute: (email: string, password: string) => Promise<LoginApiResponse>;
error: string;
}
请注意,我的示例是在 TS >= 4 上测试的。
在我的 React 项目中,我用这种模式声明了我的 api 请求:
export type LoginApiResponse = {
token: string,
user: User
}
export function login(email: string, password: string): Promise<LoginApiResponse> {
return AuthService.signinWithEmailAndPassword(email, password)
}
我通过自定义挂钩使用它们
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 };
}
像这样的实现
const loginExecutor = useApi
通过这种方式,我封装了给定 api 请求的加载和错误状态,而且我有完整的输入支持
问题
现在我的问题是:有没有办法利用打字稿类型推断来推断 fn 函数的 return 类型和参数类型,以便能够编写
useApi(api.login)
而不是
useApi<LoginApiResponse, typeof api.login>(api.login)
同时保持相同的强类型?
我看到您的示例推断了除响应之外的所有内容。它具有以下类型:
const loginExecutor = useApi(login)
const loginExecutor: {
loading: boolean;
execute: (email: string, password: string) => Promise<unknown>;
error: string;
}
我更新了 useApi
以提取参数并 return 分别输入:
export function useApi<A extends any[], T>(
fn: (...args: A) => Promise<T>
)
所以现在我们得到以下类型:
const loginExecutor = useApi(login)
const loginExecutor: {
loading: boolean;
execute: (email: string, password: string) => Promise<LoginApiResponse>;
error: string;
}
请注意,我的示例是在 TS >= 4 上测试的。