我正在尝试构建一个通用工具,以处理对 react query query usequery
在我的应用程序中请求,并使用Typescript构建此内容,以便正确键入数据。
在父组件中,用例将是这样的:
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);
};
但是,当我检查传递给孩子的 data
时,而不是作为预期响应数据的类型,这是未知的。我很难做到这一点,作为对打字稿中低级理解的人。我以为我可以应用与,但我不知道在这种情况下如何做。
我尝试了一下:
interface ReactQueryLoaderProps {
// ...
children: <T extends unknown>(data: T) => JSX.Element;
}
但是在父元素中得到了这个:
(parameter) data: T extends unknown
我也尝试了:
interface ReactQueryLoaderProps {
useQueryResult: UseQueryResult<T extends unknown, Error>;
但这引发了两个错误:
- 在t:
下找不到姓名't'。
- 在逗号下:
'?'?预期。
这可以做到吗?
I'm trying to build a generic tool for handling the response to React Query useQuery
requests in my app, and build this out using TypeScript, so that the data is correctly typed.
In a parent component, the use case would be something like this:
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>
);
I tried defining this ReactQueryLoader as so:
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);
};
But when I inspect the data
passed to the child, instead of being the type of the expected response data, it is unknown. I'm having trouble getting this to work, as someone with a mid-low-level understanding of TypeScript. I thought I could apply the same pattern as in this answer to another question I had, but I can't figure out how to do it in this context.
I tried this:
interface ReactQueryLoaderProps {
// ...
children: <T extends unknown>(data: T) => JSX.Element;
}
But got this in the parent element:
(parameter) data: T extends unknown
I also tried:
interface ReactQueryLoaderProps {
useQueryResult: UseQueryResult<T extends unknown, Error>;
But that provoked two errors:
- Under the T:
Cannot find name 'T'.
- Under the comma:
'?' expected.
Is this possible to do?
发布评论
评论(1)
ReactQueryLoader
功能在这里需要通用,以及Props类型。看起来可能是这样的:
此处
ReactQueryLoader
现在是一个通用函数,可将查询结果类型捕获为t
,并将其传递给通用props类型reactqueryloaderProps。
ReactQueryLoaderProps
然后将该类型用作usequeryResult
的类型,然后从该类型中从该类型中拉出['data']
属性,用于<代码>儿童功能参数。See playground
The
ReactQueryLoader
function needs to be generic here, as well as the props type.That might look something like this:
And
Here
ReactQueryLoader
is now a generic function that captures the query result type asT
and passes that to the generic props typeReactQueryLoaderProps
.ReactQueryLoaderProps
then uses that type as the type ofuseQueryResult
, and pulls the['data']
property from that type for the type of thechildren
function parameter.See playground