I'm starting with typescript and I'm having some doubts to make my code more solid. I have a component that is a menu with three options:
const List = ({ statusEvents }: { statusEvents: any }) => {
const match = useRouteMatch();
const handleStatusEvents = (status: string): void => {
statusEvents(status);
};
return (
<>
<ListStyled>
<li>
<NavLinkStyled
activeClassName="link"
to={`${match.path}/pendientes`}
onClick={() => handleStatusEvents("pendientes")}
>
Pendientes
</NavLinkStyled>
</li>
<li>
<NavLinkStyled
activeClassName="link"
to={`${match.path}/activas`}
onClick={() => handleStatusEvents("activas")}
>
Activas
</NavLinkStyled>
</li>
<li>
<NavLinkStyled
activeClassName="link"
to={`${match.path}/resultados`}
onClick={() => handleStatusEvents("resultados")}
>
Resultados
</NavLinkStyled>
</li>
</ListStyled>
</>
);
};
export default List;
And its parent component:
interface IPropsState {
index: number;
image: string;
title: string;
description: string;
time: string;
assistants: number;
isActive: boolean;
}
const EventPage = () => {
const [filter, setFilter] = useState<IPropsState[]>(ListOfEvents);
const handleChangeStatusEvents = (status: string) => {
switch (status) {
case "pendientes":
const pendientes = ListOfEvents.filter(
(event) => event.isActive === false
);
setFilter(pendientes);
break;
case "activas":
const activas = ListOfEvents.filter((event) => event.isActive === true);
setFilter(activas);
break;
case "resultados":
const resultados = ListOfEvents;
setFilter(resultados);
}
};
return (
<MainLayout>
<Spacer height="30" />
<Title text="Eventos" />
<Spacer height="30" />
<List statusEvents={handleChangeStatusEvents} />
{filter ? <ListEvents events={filter} /> : <EmptyEvents />}
</MainLayout>
);
};
export default EventPage;
In this menu, what it does is send a handleStatusEvents function to its predecessor component through the onClick, passing a text with the name of each category through props.
onClick={() => handleStatusEvents("pendientes")}
const handleStatusEvents = (status: string): void => {
statusEvents(status);
};
The type of the function handleStatusEvents is of type void and the arguments are of type string. When I want to pass the statusEvents to its parent (by props)
const List = ({ statusEvents }: { statusEvents: any }) => {}
I have to put :any because in the parent component, the statusEvents prop is calling a function that sets the states. So it is here what kind of typing I have to put (other than any), because on the one hand I understand that from the child component a string is "leaving" by props, but the parent is calling a function... I don't understand very well which typing would be the desired one. Thank you very much for the help.
TypeScript Interface and Function type expression
An interface
TypeScript
is used to define the form of the properties of an object, in this case the ReactJS component.Now, the form can be used
function type expression with parameter
to describe the methodhandleChangeStatusEvents
, along with ainterface
:According to the documentation of
TS
the following line:It can be interpreted as:
The method
handleChangeStatusEvents
does not have anreturn
explicit, so it can be configuredTypeScript
as a function that returnsvoid
and also expects to receive a parameter of typestring
.Next, the ReactJS component is configured to receive the interface
Props
:Hope this answer is helpful.