使用时的类型参数
Type argument at moment of use
我正在尝试构建一个通用工具来处理对我的应用程序中 React Query useQuery
请求的响应,并使用 TypeScript 构建它,以便正确输入数据。
在 parent 组件中,用例是这样的:
const queryResult = useQuery<MyResponseType, Error>('whatever');
return (
<ReactQueryLoader useQueryResult={queryResult}>
{data => {
// Data should be of MyResponseType type, but is unknown
return <pre>{JSON.stringify(data, null, 2)}</pre>;
}}
</ReactQueryLoader>
);
我试过这样定义这个 ReactQueryLoader:
import React from "react";
import { UseQueryResult } from "react-query";
import { Loading } from "./Loading";
interface ReactQueryLoaderProps {
useQueryResult: UseQueryResult<unknown, Error>;
handleError?: (error: Error) => void;
children: (data: unknown) => JSX.Element;
}
export const ReactQueryLoader = ({
useQueryResult,
handleError = error => {
console.error(error);
throw new Error(error.message);
},
children,
}: ReactQueryLoaderProps): null | JSX.Element => {
if (useQueryResult.isError) {
handleError(useQueryResult.error);
return null;
}
if (useQueryResult.isLoading) {
return <Loading />;
}
return children(useQueryResult.data);
};
但是当我检查传递给 child 的 data
时,它不是预期响应数据的类型,而是未知的。作为对 TypeScript 有 mid-low-level 理解的人,我无法让它工作。我以为我可以应用与 中相同的模式,但我不知道在这种情况下该怎么做。
我试过这个:
interface ReactQueryLoaderProps {
// ...
children: <T extends unknown>(data: T) => JSX.Element;
}
但是在 parent 元素中得到了这个:
(parameter) data: T extends unknown
我也试过:
interface ReactQueryLoaderProps {
useQueryResult: UseQueryResult<T extends unknown, Error>;
但这引发了两个错误:
- T下:
Cannot find name 'T'.
- 逗号下:
'?' expected.
这可能吗?
这里的ReactQueryLoader
函数需要是通用的,props类型也是如此。
可能看起来像这样:
interface ReactQueryLoaderProps<T extends UseQueryResult<unknown, Error>> {
useQueryResult: T;
handleError?: (error: Error) => void;
children: (data: T['data']) => JSX.Element;
}
和
export function ReactQueryLoader<T extends UseQueryResult<unknown, Error>>({
useQueryResult,
handleError,
children,
}: ReactQueryLoaderProps<T>): null | JSX.Element {
//...
}
这里 ReactQueryLoader
现在是一个通用函数,它将查询结果类型捕获为 T
并将其传递给通用道具类型 ReactQueryLoaderProps
.
ReactQueryLoaderProps
然后使用该类型作为 useQueryResult
的类型,并从该类型中提取 ['data']
属性 作为 children
的类型函数参数。
我正在尝试构建一个通用工具来处理对我的应用程序中 React Query useQuery
请求的响应,并使用 TypeScript 构建它,以便正确输入数据。
在 parent 组件中,用例是这样的:
const queryResult = useQuery<MyResponseType, Error>('whatever');
return (
<ReactQueryLoader useQueryResult={queryResult}>
{data => {
// Data should be of MyResponseType type, but is unknown
return <pre>{JSON.stringify(data, null, 2)}</pre>;
}}
</ReactQueryLoader>
);
我试过这样定义这个 ReactQueryLoader:
import React from "react";
import { UseQueryResult } from "react-query";
import { Loading } from "./Loading";
interface ReactQueryLoaderProps {
useQueryResult: UseQueryResult<unknown, Error>;
handleError?: (error: Error) => void;
children: (data: unknown) => JSX.Element;
}
export const ReactQueryLoader = ({
useQueryResult,
handleError = error => {
console.error(error);
throw new Error(error.message);
},
children,
}: ReactQueryLoaderProps): null | JSX.Element => {
if (useQueryResult.isError) {
handleError(useQueryResult.error);
return null;
}
if (useQueryResult.isLoading) {
return <Loading />;
}
return children(useQueryResult.data);
};
但是当我检查传递给 child 的 data
时,它不是预期响应数据的类型,而是未知的。作为对 TypeScript 有 mid-low-level 理解的人,我无法让它工作。我以为我可以应用与
我试过这个:
interface ReactQueryLoaderProps {
// ...
children: <T extends unknown>(data: T) => JSX.Element;
}
但是在 parent 元素中得到了这个:
(parameter) data: T extends unknown
我也试过:
interface ReactQueryLoaderProps {
useQueryResult: UseQueryResult<T extends unknown, Error>;
但这引发了两个错误:
- T下:
Cannot find name 'T'.
- 逗号下:
'?' expected.
这可能吗?
这里的ReactQueryLoader
函数需要是通用的,props类型也是如此。
可能看起来像这样:
interface ReactQueryLoaderProps<T extends UseQueryResult<unknown, Error>> {
useQueryResult: T;
handleError?: (error: Error) => void;
children: (data: T['data']) => JSX.Element;
}
和
export function ReactQueryLoader<T extends UseQueryResult<unknown, Error>>({
useQueryResult,
handleError,
children,
}: ReactQueryLoaderProps<T>): null | JSX.Element {
//...
}
这里 ReactQueryLoader
现在是一个通用函数,它将查询结果类型捕获为 T
并将其传递给通用道具类型 ReactQueryLoaderProps
.
ReactQueryLoaderProps
然后使用该类型作为 useQueryResult
的类型,并从该类型中提取 ['data']
属性 作为 children
的类型函数参数。