Reputation: 4685
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
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