I'm building a component library using React, TypeScript, Styled Components, and Rollup. Now I've created a Button component using a type interface. I then roll up the library to install it locally in my test project. I then import the Button and try to use it. I have defined two props for the button: children and type. Children is of type React.ReactNode, and type is of type String. Now when I use the Button component in my test project is keeps saying the following:
Type '{ children: string; type: string; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. Property 'children' does not exist on type 'IntrinsicAttributes & ButtonProps'.
Below is my type interface for the Button:
import React from "react";
export type ButtonProps = {
type: String;
children: React.ReactNode;
};
And below if my Button:
import React from "react";
import { ButtonBase } from "./button.style";
import { ButtonProps } from "./button.types";
function getButton(type: String) {
switch (type) {
case "base":
return ButtonBase;
default:
return ButtonBase;
}
}
const Button = ({ type, children }: ButtonProps) => {
const Component = getButton(type);
return <Component>{children}</Component>;
};
export default Button;
And this is how I then use the Button in my test project:
import { Button } from "aab-react-emerald";
function App() {
return (
<div className="App">
<header className="App-header"></header>
<Button type="base">Button</Button>
</div>
);
}
This is my ButtonBase. It is a Styled Component which inherits some styling from a basic Button component. There will be two more buttons, which both will inherit some default styling.
import styled from "styled-components";
import theme from "@theme";
const Button = styled.button`
display: flex;
justify-content: center;
align-items: center;
border: none;
padding: 8px 16px;
height: 40px;
box-shadow: none;
font-size: 16px;
line-height: 24px;
border-radius: 2px;
cursor: pointer;
transition: background-color ${theme.transition};
transition: ${theme.transition};
`;
export const ButtonBase = styled(Button)`
color: white;
background-color: ${theme.colors.g300};
:hover {
background-color: ${theme.colors.g200};
}
:active {
background-color: ${theme.colors.g400};
}
`;
Does anyone know what I should do differently?
CodePudding user response:
In this code here
<Button type="base">Button</Button>
'children' is in fact a string, not a ReactNode - that's why it's getting rejected, the types don't match. If you allow a string in your type definition that should fix it:
children: React.ReactNode | string;
CodePudding user response:
You can define the component with the React.FC
type, which adds the children
prop to the props
. For example:
import React from "react";
import { ButtonBase } from "./button.style";
import { ButtonProps } from "./button.types";
function getButton(type: String) {
switch (type) {
case "base":
return ButtonBase;
default:
return ButtonBase;
}
}
// Using FC there's no need to add the children props into ButtonProps
// as it is already defined in the FC.
const Button: React.FC<ButtonProps> = ({ type, children }) => {
const Component = getButton(type);
return <Component>{children}</Component>;
};
export default Button;
Here you have an interesting explanation about the
React.FC
type!