I am converting my project files from jsx to tsx. For normal proptypes, I am able to provide equivalent in interface. But for custom Proptypes I am unable to do the same. please find below the example scenario to get an idea.
const AppContainer = (props) => {
return <div>{/*my component*/}</div>;
};
const customPropCheck = (props, propName, componentName) => {
if (
(props.primaryValue && !props.secondaryValue) ||
(!props.primaryValue && props.secondaryValue)
) {
return new Error(`Error for ${componentName} `);
}
return null;
};
AppContainer.defaultProps = {
primaryValue: null,
secondaryValue: null,
};
AppContainer.propTypes = {
primaryValue: customPropCheck,
secondaryValue: customPropCheck,
};
export default AppContainer;
interface AppContainerProps {
primaryValue: Error | null;
secondaryValue: Error | null;
}
const AppContainer = ({
primaryValue = null,
secondaryValue = null,
}: AppContainerProps) => {
return <div>{/*my component*/}</div>;
};
export default AppContainer;
How do i implement customPropCheck in my tsx? Is there any way Or do I have to copy same propType implementation in my tsx file ie:
AppContainer.propTypes = {
primaryValue: customPropCheck,
secondaryValue: customPropCheck
}
TypeScript can help with the type aspect of prop-types, but if you want custom checks like yours to be applied when the props are specified (instead of later when the component is rendered), you still need prop-types to do that.
As far as I can tell, there's no special problem using it. The types of the parameters in customPropCheck are AppContainerProps, keyof AppContainerProps, and string respectively.
const customPropCheck = (props: AppContainerProps, propName: keyof AppContainerProps, componentName: string) => {
if (
(props.primaryValue && !props.secondaryValue) ||
(!props.primaryValue && props.secondaryValue)
) {
return new Error(`Error for ${componentName} `);
}
return null;
};
Then you just assign to the function (I was expecting this to be a problem, but it doesn't seem to be):
AppContainer.defaultProps = {
primaryValue: null,
secondaryValue: null,
};
AppContainer.propTypes = {
primaryValue: customPropCheck,
secondaryValue: customPropCheck,
};
The defaultProps part of that is conceptually redundant, you're specifying defaults in the destructuring in your component props, but again those will get applied once when the element is created, not repeatedly when the component for it gets rendered, so there might be an argument for keeping it (although your custom check doesn't rely on it, you'll see undefined instead of null but your checks don't care about the distinction).