mxmtsk
mxmtsk

Reputation: 4685

Typescript throws error with spread operator

I have the following simple React component:

export interface BadgeProps {
  children: React.ReactNode | string | React.ReactNode[],
  layout: "gray" | "danger" | "success" | "brand",
  size?: "sm" | "base",
}

const Badge: React.FC<BadgeProps> = ({ children }) => {
  return (
    <div data-test="component-badge">{children}</div>
  );
}

When I now call the component this way it works fine:

<Badge layout="gray">Text</Badge>

But when I pass the props with a spread operator, I get the following error.

const props = { layout: "gray" };
return (
  <Badge {...props}>Text</Badge>
);

Type 'string' is not assignable to type '"gray" | "danger" | "success" | "brand"'

I feel like it should just work fine and I have no idea why it fails. Is this a misunderstanding of how Typescript works?

Upvotes: 4

Views: 790

Answers (1)

felixmosh
felixmosh

Reputation: 35473

It because "gray" | "danger" | "success" | "brand" is a specific type that can be only one of those strings, but when you assigning like this:

const props = { layout: "gray" };

Typescript infers that layout property is a string and not your special type, therefore the error.

In order to fix this error, you need to mark the type yourself.

export type LayoutType = "gray" | "danger" | "success" | "brand";

export interface BadgeProps {
  children: React.ReactNode | string | React.ReactNode[],
  layout: LayoutType,
  size?: "sm" | "base",
}

const Badge: React.FC<BadgeProps> = ({ children }) => {
  return (
    <div data-test="component-badge">{children}</div>
  );
}



const props: { layout: LayoutType } = { layout: "gray" };
// ------------------------^ your layout type 
return (
  <Badge {...props}>Text</Badge>
);

Upvotes: 1

Related Questions