我有一个简单的 react 钩子(Hook),它接受一个参数,一个异步函数。它有效,但是在使用钩子(Hook)时我没有得到任何类型推断。具体来说,我试图让 typescript 推断正在传递的回调参数的类型。我提供了下面的代码以及我当前对该函数的使用情况。
Hook :
import { useCallback, useState } from "react";
type UseAsync<T> = [{ result: T; loading: boolean; error: string }, (...args) => void];
export const useAsync = <T>(asyncFn: (...args) => Promise<T>): UseAsync<T> => {
const [loading, setLoading] = useState(false);
const [result, setResult] = useState(null);
const [error, setError] = useState(null);
const callback = useCallback(
async (...args) => {
try {
setLoading(true);
const result = await asyncFn(...args);
setResult(result);
} catch (e) {
setError(e);
} finally {
setLoading(false);
}
},
[asyncFn]
);
return [{ result, loading, error }, callback];
};
export default useAsync;
我的用法:
const [{ result, loading, error }, postOrder] = useAsync((data: INewOrderFormData) =>
Axios.post("/api/order", data)
);
当我将鼠标悬停在 VSCode 中的“postOrder”上时,我看到 const postOrder: (...args: any[]) => void
其中 args 在应该引用时被定义为 any[]传递到 Hook 的函数的参数类型(如果有)。
最佳答案
如果向 UseAsync
和 useAsync
添加额外的泛型参数 A extendsknown[]
,则可以跟踪参数类型,并用它键入每个出现的 ...args
。
结果看起来像这样(我必须调整一些 null
类型,可能是因为代码不是使用 strictNullChecks
编译的):
type UseAsync<T, A extends unknown[]> =
[{ result: T | null; loading: boolean; error: string }, (...args: A) => void];
export const useAsync = <T, A extends unknown[]>(asyncFn: (...args: A) => Promise<T>): UseAsync<T,A> => {
const [loading, setLoading] = useState(false);
const [result, setResult] = useState<T | null>(null);
const [error, setError] = useState<any>(null);
const callback = useCallback(
async (...args: A) => {
try {
setLoading(true);
const result = await asyncFn(...args);
setResult(result);
} catch (e) {
setError(e);
} finally {
setLoading(false);
}
},
[asyncFn]
);
return [{ result, loading, error }, callback];
};
当应用于测试函数时,postOrder
的类型具有实际的参数类型:
type INewOrderFormData = {}
const [{ result, loading, error }, postOrder] =
useAsync(async (data: INewOrderFormData, arg2: symbol) => 42);
type Test = typeof postOrder
// inferred type: (data: INewOrderFormData, arg2: symbol) => void
关于reactjs - Typescript:推断作为参数传递给另一个函数的回调函数的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67221698/