Я пытаюсь написать общий помощник компонента-обертки, запрашивающий 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 различными способами, но пока не получил его работу: (