我正在尝试编写一个通用的API查询包装器组件助手,并希望以通用类型(使用TypeScript)键入它,以便支持对特定API端点的参数和结果进行类型检查。除了React-Redux connect
包装程序之外,我可以完成此工作,在该包装程序上似乎无法携带帮助程序的通用定义。
import React from "react";
import { connect } from "react-redux";
// import Api from "../somewhere";
declare const Api: { fetch: (params: any) => any };
interface Props<Result, Params> {
accessToken?: string;
params: Params;
children: (fetchState: { loading: boolean; result?: Result; error?: any }) => React.ReactNode;
}
function ApiQueryComponent<Result, Params>({
accessToken,
params,
children
}: Props<Result, Params>) {
if (accessToken) {
// Actually use the API here ...
const promise = Api.fetch({ accessToken, params }) as Promise<Result>;
const result = ({ id: 5, title: "shoes" } as unknown) as Result;
return <div>{children({ loading: false, result })}</div>;
} else {
return <div>Please login first</div>;
}
}
function mapStateToProps(state: { accessToken?: string }) {
return {
accessToken: state.accessToken
};
}
export const ApiQuery = connect(mapStateToProps)(ApiQueryComponent);
// ======
// UI.tsx
// ======
declare const Product: React.ComponentType<{ product: any }>;
declare interface IProduct {}
// Does not type-check, "Expected 0 type arguments, but got 2"
export function UI() {
return (
<ApiQuery<IProduct, { id: number }> params={{ id: 5 }}>
{({ loading, result: product, error }) => {
if (loading) return <div>Loading...</div>;
else if (error) return <div>Error :(</div>;
else return <Product product={product} />;
}}
</ApiQuery>
);
}
// Type-checks as expected, `product` is an `IProduct`
export function UI2() {
return (
<ApiQueryComponent<IProduct, { id: number }> params={{ id: 5 }}>
{({ loading, result: product, error }) => {
if (loading) return <div>Loading...</div>;
else if (error) return <div>Error :(</div>;
else return <Product product={product} />;
}}
</ApiQueryComponent>
);
}
在此代码中,UI2
可以正常工作,您可以告诉它参数和数据的类型。但是在UI
中,由于使用connect
包装器,因此无法指定此信息。
有人知道如何继承仿制药吗?我曾尝试以各种方式包装connect
ed组件,但尚未使其起作用:(