Published: August 02 2023

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

On Twitter or RSS.


When I'm not coding...

Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!


Comments


Supported by