TypeScript React помогите типизировать компонент в HOC в route
Я сделал обёртку для формы, которая в зависимости от роута передает в форму разные колбэки, на создание и на обновление сущности, но когда я вызываю этот HOC в роуте и передаю ему компонент формы, ts ругается на типизацию оборачиваемого компонента
Код обертки
type ComponentProps<EditEnity, CreateEntity> = {
callback: (task: EditEnity | CreateEntity) => Promise<void>
}
type Props<EditEnity, CreateEntity, ServiceType> = {
Component: React.ComponentClass<ComponentProps<EditEnity, CreateEntity>>
service: ServiceType
} & RouteComponentProps<RouteParams>
type RouteParams = {
taskId: string
}
function FormWrapper<EditEnity extends BaseEntity, CreateEntity, ServiceType extends RestPaginationService<EditEnity, CreateEntity> = RestPaginationService<EditEnity, CreateEntity>>({
Component,
service,
...props
}: Props<EditEnity, CreateEntity, ServiceType>) {
const isTaskToEdit = (taskEntity: EditEnity | CreateEntity): taskEntity is EditEnity => {
return (taskEntity as EditEnity).id !== undefined
}
const submitHandler = (taskEntity: EditEnity | CreateEntity) => {
if (isTaskToEdit(taskEntity)) {
return service.update(taskEntity)
}
return service.add(taskEntity as CreateEntity)
}
return <Component {...props} callback={submitHandler} />
}
const CustomFormWrapper = <EditEnity, CreateEntity>() => FormWrapper
export default CustomFormWrapper
Вызываю его в роуте
<Route
path="/admin/tasks/ordering/add"
exact
//@ts-ignore
render={props => <CustomFormComponent {...props} service={service} Component={OrderingTaskForm} />}
/>
<Route
path="/admin/tasks/ordering/edit/:taskId"
exact
//@ts-ignore
render={props => <CustomFormComponent {...props} service={service} Component={OrderingTaskForm} />}
/>
если поставлю any в типе оборачиваемого компонента ошибки нет
type Props<EditEnity, CreateEntity, ServiceType> = {
Component: React.ComponentClass<any>
service: ServiceType
} & RouteComponentProps<RouteParams>
Буду рад любой помощи
Ответы (1 шт):
Автор решения: Denis Merioara
→ Ссылка
Я не понимаю полную идею кода, вот пример HOC в связке с react-roter
import React, { useCallback } from "react";
import ReactDOM from "react-dom";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useRouteMatch,
} from "react-router-dom";
import type { RouteComponentProps } from "react-router-dom";
import reportWebVitals from "./reportWebVitals";
interface DefaultComponentProps extends RouteComponentProps<any> {
handler: () => void;
service: Object;
}
const DefaultComponent = (props: DefaultComponentProps) => {
const { handler } = props;
return <button onClick={handler}>click</button>;
};
const ContentHOC = (props: Omit<DefaultComponentProps, "handler">) => {
const {
params: { id },
} = (useRouteMatch("/:id") ?? { params: { id: null } }) as {
params: { id: string | null };
};
const callback = useCallback(() => {
if (id === null) return alert("Home page");
alert("any page");
}, [id]);
return <DefaultComponent {...props} handler={callback} />;
};
function App() {
return (
<div className="App">
<Router>
<header className="App-header">
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
</header>
<div>
<Switch>
<Route
exact
render={(props: RouteComponentProps<any>) => (
<ContentHOC {...props} service={{}} />
)}
/>
<Route
path="/about"
render={(props) => <ContentHOC {...props} service={{}} />}
/>
</Switch>
</div>
</Router>
</div>
);
}
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
