I am currently migrating a Next.js project from JavaScript to TypeScript, and I've run into an error: Property 'className' does not exist on type '{ props: ReactNode; }'
. In Javascript, I can extract className from props but typescript cannot find the type. Here is the code:
import { useRouter } from 'next/router'
import Link from 'next/link'
import { ReactNode } from 'react'
export { NavLink }
NavLink.defaultProps = {
exact: false,
}
interface NavLinkProps {
href: string
exact?: boolean
children: ReactNode
props: ReactNode
}
function NavLink({ href, exact, children, ...props }: NavLinkProps) {
const { pathname } = useRouter()
const isActive = exact ? pathname === href : pathname.startsWith(href)
if (isActive) {
props.className += ' active'
}
return (
<Link href={href}>
<a {...props}>{children}</a>
</Link>
)
}
}
I am currently migrating a Next.js project from JavaScript to TypeScript, and I've run into an error: Property 'className' does not exist on type '{ props: ReactNode; }'
. In Javascript, I can extract className from props but typescript cannot find the type. Here is the code:
import { useRouter } from 'next/router'
import Link from 'next/link'
import { ReactNode } from 'react'
export { NavLink }
NavLink.defaultProps = {
exact: false,
}
interface NavLinkProps {
href: string
exact?: boolean
children: ReactNode
props: ReactNode
}
function NavLink({ href, exact, children, ...props }: NavLinkProps) {
const { pathname } = useRouter()
const isActive = exact ? pathname === href : pathname.startsWith(href)
if (isActive) {
props.className += ' active'
}
return (
<Link href={href}>
<a {...props}>{children}</a>
</Link>
)
}
}
Share
Improve this question
edited Oct 14, 2021 at 20:23
Gravy59
asked Oct 14, 2021 at 20:05
Gravy59Gravy59
871 gold badge2 silver badges6 bronze badges
4
-
3
just add
className?: string
to your NavLinkProps interface and handle undefined className case. – Roman Kurbatov Commented Oct 14, 2021 at 20:28 - And that's a bad patter to modify props you've got. – Roman Kurbatov Commented Oct 14, 2021 at 20:31
- @RomanKurbatov What would be a better pattern? – Gravy59 Commented Oct 14, 2021 at 20:41
-
1
try
classnames
package, it will simplify dealing with multiple classes. You can use something like{...props} {className: {classnames(props.className, { active: isActive }}
overriding original className and having multiple conditions. – Roman Kurbatov Commented Oct 14, 2021 at 20:47
1 Answer
Reset to default 4Your interface declaring NavLinkProps
is wrong. You shouldn't add props
because you're spreading the rest of the object which would be anything in the interface after href
, exact
and children
. The interface should look like this:
interface NavLinkProps {
href: string
exact?: boolean
children: ReactNode
className: string
// any other props you might have
}
So the props object that exists from spreading – ...props
would be:
{
className,
// any other props you might have
}
see this doc for more info – https://reactjs/docs/jsx-in-depth.html#spread-attributes