TypeScript 2.1 now supports object spread/rest, so no workarounds are needed anymore!
TypeScript supports JSX spread attributes which is commonly used in React to pass HTML attributes from a component to a rendered HTML element:
interface LinkProps extends React.HTMLAttributes { textToDisplay: string; } class Link extends React.Component<LinkProps, {}> { public render():JSX.Element { return ( <a {...this.props}>{this.props.textToDisplay}</a> ); } } <Link textToDisplay="Search" href="http://google.com" />
However, React introduced a warning if you pass any unknown props to an HTML element. The above example would produce a React runtime warning that textToDisplay
is an unknown prop of <a>
. The suggested solution for a case like this example is to use object rest properties to extract out your custom props and use the rest for the JSX spread attributes:
const {textToDisplay, ...htmlProps} = this.props; return ( <a {...htmlProps}>{textToDisplay}</a> );
But TypeScript does not yet support this syntax. I know that hopefully some day we will be able to do this in TypeScript. (Update: TS 2.1 now supports object spread/rest! Why are you still reading this??) In the meantime what are some workarounds? I'm looking for a solution that doesn't compromise type-safety and finding it surprisingly difficult. For example I could do this:
const customProps = ["textDoDisplay", "otherCustomProp", "etc"]; const htmlProps:HTMLAttributes = Object.assign({}, this.props); customProps.forEach(prop => delete htmlProps[prop]);
But this requires the use of string property names that are not validated against the actual props and thus prone to typos and bad IDE support. Is there a better way we can do this?
To add types for rest props in React and TypeScript, we can add an index signature into the prop's type. [x: string]: any; index signature that lets us allow any property in props . Then we can access any property in addition to id and name without errors.
To pass an array as a prop to a component in React, wrap the array in curly braces, e.g. <Books arr={['A', 'B', 'C']} /> . The child component can perform custom logic on the array or use the map() method to render the array's elements. Copied!
Not only can JSX elements be passed as props to components, but we can also pass other components as props. In fact, there is a special type of prop that is automatically provided on the props object called children .
You can use the <></> Fragments to pass the HTML in the props.
It's actually easier than all of the answers above. You just need to follow the example below:
type Props = { id: number, name: string; // All other props [x:string]: any; } const MyComponent:React.FC<Props> = props => { // Any property passed to the component will be accessible here }
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With