Patryk Janik
Patryk Janik

Reputation: 2623

className is missing for styled component

I have defined such "Logo" component:

const Logo = ({ className }: { className: string }) => (
  <Link to="/" className={className}>
    <img src={logo} alt="logo" />
  </Link>
);

Which has the open possibility to be styled with passing down className.

But when I'm using it with the typescript like that:

const StyledLogo = styled(Logo)`
  margin-left: 4.5rem;
`;

... somewhere in render:

<StyledLogo />

Then I've got such error:

Error:(33, 6) TS2741: Property 'className' is missing in type '{}' but required in type 'Pick & Partial>, "className">'.

How to let know typescript that all my styled components will pass down this className property and it will be always there?

Upvotes: 3

Views: 2066

Answers (1)

Dacre Denny
Dacre Denny

Reputation: 30390

It should be possible to resolve this issue by marking the className parameter of Logo as optional by doing the following:

/* Add ? after className */
const Logo = ({ className }: { className?: string }) => (
  <Link to="/" className={className}>
    <img src={logo} alt="logo" />
  </Link>
);

const StyledLogo = styled(Logo)`
  margin-left: 4.5rem;
`;

/* No ts error reported now */
<StyledLogo />

Hope that helps!


Update

Alternatively, to avoid the optional className method above you can take this approach:

/* Define type to minimise verbosity */
type LogoProps = { className: string };

/* Define strongly typed Logo function with defined type */
const Logo = (props: LogoProps) => (
  <Link to="/" className={props.className}>
    <img src={"logo"} alt="logo" />
  </Link>
);

/* TS explicitly aware of prop set being passed to Logo via type */
export const StyledLogo = styled((props: LogoProps) => <Logo {...props} />)`
  margin-left: 4.5rem;
`;

 /* Usage */
 <StyledLogo />

This method ensures that TS is aware of the actual prop set being passed to the Logo component.

Upvotes: 1

Related Questions