Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript workaround for rest props in React

Updated for TypeScript 2.1

TypeScript 2.1 now supports object spread/rest, so no workarounds are needed anymore!


Original Question

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?

like image 453
Aaron Beall Avatar asked Oct 13 '16 23:10

Aaron Beall


People also ask

How do you write rest props in React?

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.

Can I pass array as props React?

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!

Can props pass JSX?

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 .

Can we pass HTML as props in React?

You can use the <></> Fragments to pass the HTML in the props.


1 Answers

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.

like image 56
Willy Avatar answered Oct 07 '22 08:10

Willy