提问人:paternostrox 提问时间:11/8/2023 最后编辑:paternostrox 更新时间:11/8/2023 访问量:42
Typescript:具有多个泛型函数作为参数的函数
Typescript: Function with multiple generic functions as params
问:
我正在尝试扩展这个现有函数(自定义反应钩子),它目前需要两个通用的获取函数,并将它们的响应数据作为命名元组以及一些辅助变量返回。我需要它接受任意数量的函数作为参数,然后返回一个名为元组的拟合,其中包含相应的响应数据类型(和辅助数据)。
我尝试使用不同类型的 rest 参数,但仍然没有运气,似乎无法使函数返回正确的结构。任何帮助都是值得赞赏的!
export function useFetchMultipleDataMunicipio<T0, T1>(
f0: (routeProps: IMunicipioRouteProps, prestacaoContext: IPrestacaoContextProps, settings: ISettings) => AxiosPromise<T0>,
f1: (routeProps: IMunicipioRouteProps, prestacaoContext: IPrestacaoContextProps, settings: ISettings) => AxiosPromise<T1>,
) {
const routeProps = useMunicipioContext().municipioRouteProps;
const prestacaoContext = usePrestacaoContext();
const { settings } = useSettingsContext();
const [dataTuple, setDataTuple] = useState<[T0, T1]>();
const [loading, setLoading] = useState(true);
useEffect(() => {
if (_.isEmpty(routeProps) || prestacaoContext.loading) {
return;
}
Promise.all([f0(routeProps, prestacaoContext, settings), f1(routeProps, prestacaoContext, settings)])
.then((response) => {
const newDataTuple: [T0,T1] = [response[0].data, response[1].data];
setDataTuple(newDataTuple);
})
.finally(() => {
setLoading(false);
});
return () => {
setDataTuple(undefined);
setLoading(true);
}
}, [routeProps, prestacaoContext.loading]);
return { dataTuple, loading, routeProps, prestacaoContext, settings };
}
答:
1赞
Ben
11/8/2023
#1
我想你正在寻找这样的东西:
type FetchFunction<T> = (
routeProps: IMunicipioRouteProps,
prestacaoContext: IPrestacaoContextProps,
settings: ISettings
) => AxiosPromise<T>;
type FetchFunctionResponseTypes<T extends Array<FetchFunction<unknown>>> = {
[P in keyof T]: T[P] extends FetchFunction<infer R> ? R : never;
};
然后,您应该能够将这些类型与钩子声明一起使用,如下所示:
function useFetchMultipleDataMunicipio<T extends Array<FetchFunction<unknown>>>(...args: T) {
// ...
const [dataTuple, setDataTuple] =
useState<FetchFunctionResponseTypes<typeof args>>();
// ...
useEffect(() => {
const promises = args.map(func => func(routeProps, prestacaoContext, settings));
Promise.all(promises)
.then((response) => {
const newDataTuple = response.map(
(res) => res.data
) as FetchFunctionResponseTypes<T>;
setDataTuple(newDataTuple);
})
.finally(() => {
setLoading(false);
});
}, [routeProps, prestacaoContext.loading]);
return { dataTuple, loading, routeProps, prestacaoContext, settings };
}
评论
1赞
paternostrox
11/10/2023
完美无缺,谢谢Ben
评论