Reactjs Typescript:推断作为参数传递给另一个函数的回调函数的参数
我有一个简单的react钩子,它接受一个参数,一个异步函数。它可以工作,但是在使用钩子时,我没有得到任何类型推断。具体来说,我试图让typescript推断所传递回调的参数类型。我已经提供了下面的代码和我当前使用的函数 钩子:Reactjs Typescript:推断作为参数传递给另一个函数的回调函数的参数,reactjs,typescript,react-hooks,Reactjs,Typescript,React Hooks,我有一个简单的react钩子,它接受一个参数,一个异步函数。它可以工作,但是在使用钩子时,我没有得到任何类型推断。具体来说,我试图让typescript推断所传递回调的参数类型。我已经提供了下面的代码和我当前使用的函数 钩子: import { useCallback, useState } from "react"; type UseAsync<T> = [{ result: T; loading: boolean; error: string }, (...
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”上时,我看到
常量postOrder:(…args:any[])=>void
其中args被定义为any[],它应该引用传递到钩子中的函数的参数类型(如果有的话)。如果添加一个额外的泛型参数A extends unknown[]
同时输入UseAsync
和UseAsync
,并用它键入每个出现的…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];
};
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