I was reading this tutorial for some clues on how to use types in my components. But the feeling I get so far is that it is contrived and verbose. From a nice terse code we get to something really hard to read. What is the most elegant way to do this? It seems that information on this subject is scarce and often outdated. Not so many people using TS with React.
Is React.StatelessComponent<React.HTMLProps<JSX.Element>>
better than React.StatelessComponent<{}>
?
It all started from this error [ts] Property 'propTypes' does not exist on type '({match, onClick, completed, text}: EntityPage) => Element'.
My current setup:
import * as React from "react";
import { PropTypes } from "react";
import * as classNames from 'classnames';
interface EntityPage {
match: any,
onClick(): void,
completed: boolean,
text: string
}
export const EntityPageCmp: React.StatelessComponent<{}> =
({ match, onClick, completed, text }: EntityPage) => {
// Styles
require('./entity-page.cmp.scss');
let classes = classNames('entity-page-cmp'),
titleClasses = classNames('title', { active: completed });
return (
<div className={classes} >
<h3 className={titleClasses}>
Entity: {match.params.entityId}
</h3>
{text}
</div>
)
}
EntityPageCmp.propTypes = {
onClick: PropTypes.func.isRequired,
completed: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired
}
export default EntityPageCmp
StatelessComponent interface takes your prop definitions as a type paremeter so you should write it like that
export const EntityPageCmp: React.StatelessComponent<EntitPage> =
({ match, onClick, completed, text }) => {
...
}
I see that you declared props two times. One in typescript way and second time in react way.
Typescript gives you type safety during compilaton time and to get that this line is enough: React.StatelessComponent<EntitPage>
In opposite to Typescript props, React props give you validation during runtime, error will appear on console when react detects wrong property type. If you would like to have that you need to write React props.
For most cases Typescript validation is enough so you don't need to repeat your props and you can delete these lines
EntityPageCmp.propTypes = {
onClick: PropTypes.func.isRequired,
completed: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired
}
If you really want to have the both you can use some libraries like https://github.com/gcanti/prop-types-ts to get that without boilerplate. Unfortunately typescript doesn't support it natively. Here is an open issue for that https://github.com/Microsoft/TypeScript/issues/4833