Using ...rest to Remove Properties from an Object
Posted 2021-02-02
Sometimes an object will have most of the properties I want to forward to another component. For example, consider this component for a blog post page:
interface Props {
title: string;
body: string[];
tags: string[];
}
export const Page = (props: Props) => {
return <div>
<h1>{props.title}<h1>
{props.body.map(paragraph => <p>{paragraph}</p>)}
</div>
}
Suppose I wanted to add a component to manage SEO tags for this page. An abbreviated version of that component could be something like this:
interface Props {
title?: string;
body?: string[];
keywords?: string[];
}
export const SEO = (props: Props) => {
return ...
}
It could then be added to page like so:
export const Page = (props: Props) => {
return <div>
<SEO {...props} />
...
Passing {…props} works, but there’s a catch. Instead of calling them tags, SEO calls them keywords. Spreading the props this way results in an empty keywords prop. For this, the rest syntax can help out.
Before passing props into SEO, I’ll destructure the problematic attribute out of props. Now there are two variables: tags and rest. rest contains title and body, which I can spread into SEO unchanged. Finally, I pass in tags with the correct name.
export const Page = (props: Props) => {
const {tags, ...rest} = props; <-- rest destructuring
return <div>
<SEO keywords={tags} {...rest} />. <-- correct name
<h1>{props.title}<h1>
{props.body.map(paragraph => <p>{paragraph}</p>)}
</div>
}
If the SEO component is under my control, I could just change keywords to tags. That’s honestly the simplest route. But sometimes you have to work with what you got, and it’s cases like these where the rest syntax can lend a hand.