TypeScript - Set type on ...rest (spread) parameter in destructured object with TS interface
I created the below NavLink
React component recently as part of a Next.js 13 tutorial built with TypeScript.
It extends the built-in Next.js Link
component to add the CSS className "active"
when the href
matches the current URL.
The NavLink
component accepts four params in a destructured object - { children, href, exact, ...props }
. The last param (...props
) uses the JavaScript spread operator (...
) to accept any extra properties so they can be added to the returned Next.js Link
component.
TypeScript interface with a ...rest
parameter
The thing I got stuck on was how to define the type for a ...rest
parameter in a TypeScript interface.
After some digging around the solution I found was to add a TypeScript Index Signature to the interface. An index signature is used when you don't know property names ahead of time but do know property key and value types, it's defined as [key: KeyType]: ValueType
.
In the below INavLink
interface the index signature [key: string]: any
allows for any property with key type string
and value type any
to be passed to a NavLink
component. Any extra properties (other than children, href, exact
) are bound to the ...props
parameter.
'use client';
import { usePathname } from 'next/navigation';
import Link from 'next/link';
export { NavLink };
function NavLink({ children, href, exact, ...props }: INavLink) {
const pathname = usePathname();
const isActive = exact ? pathname === href : pathname.startsWith(href);
if (isActive) {
props.className += ' active';
}
return <Link href={href} {...props}>{children}</Link>;
}
interface INavLink {
children: React.ReactNode,
href: string,
exact?: boolean,
[key: string]: any
}
Need Some TypeScript Help?
Search fiverr for freelance TypeScript developers.
Follow me for updates
When I'm not coding...
Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!