Emotion: TypeScript error when component renders a styled component

Created on 18 Feb 2020  路  5Comments  路  Source: emotion-js/emotion

Current behavior:
I'm using styled to create a button. In my implementation, my button is a function component that returns a styled component.

TypeScript throws an error when I use it.

To reproduce:
My button implementation

// Button.tsx

type Size = "small" | "medium" | "large";

type ButtonProps = {
  size?: Size;
  kind?:
    | "primary"
    | "text-primary"
    | "cta"
    | "gray"
    | "danger"
    | "danger-neutral"
    | "warning";
  link?: boolean;
};

const ButtonStyled = styled.button`
/* styles */
`
const Button = (props: ButtonProps) => <ButtonStyled {...props} />

export default Button;
import Button from 'Button.tsx';

// tsx does not complain
<Button size='small'></Button>
// tsx does not complain
<Button>foo</Button>
// tsx complains
<Button size='small'>foo</Button>
Type '{ children: string; size: "small"; }' is not assignable to type 'IntrinsicAttributes & Pick<Pick<ButtonProps, "size" | "link" | "kind"> & Pick<InferProps<{ size: Requireable<string>; kind: Requireable<string>; link: Requireable<...>; }>, never> & Pick<...>, never> & Partial<...> & Partial<...>'.
  Property 'children' does not exist on type 'IntrinsicAttributes & Pick<Pick<ButtonProps, "size" | "link" | "kind"> & Pick<InferProps<{ size: Requireable<string>; kind: Requireable<string>; link: Requireable<...>; }>, never> & Pick<...>, never> & Partial<...> & Partial<...>'
  • react version: 16.12.0
  • emotion version: 10.0.27
TypeScript question

Most helpful comment

@criles25 React types exposes ComponentProps type. It will extract the types of a component, so no need to manually add HTMLProps. I would try:

const Button: React.FC<ButtonProps & React.ComponentProps<'button'>> = (props) => <ButtonStyled {...props} />

All 5 comments

Try this:

const Button: React.FC<ButtonProps> = (props) => <ButtonStyled {...props} />

I tried ^.

Now I get this when I try to pass an onClick prop.

<Button onClick={onClick} kind={kind}>foo</Button>
Type '{ children: string; onClick: () => void; kind: "primary" | "text-primary" | "cta" | "gray" | "danger" | "danger-neutral" | "warning"; }' is not assignable to type 'IntrinsicAttributes & ButtonProps & { children?: ReactNode; }'.
  Property 'onClick' does not exist on type 'IntrinsicAttributes & ButtonProps & { children?: ReactNode; }'.

Edit: also thanks for your help, I'm new to typescript

The solution is to use the React.HTMLProps.

const Button: React.FC<ButtonProps & React.HTMLProps<HTMLButtonElement>> = (props) => <ButtonStyled {...props} />

@criles25 React types exposes ComponentProps type. It will extract the types of a component, so no need to manually add HTMLProps. I would try:

const Button: React.FC<ButtonProps & React.ComponentProps<'button'>> = (props) => <ButtonStyled {...props} />

I'm going to close this issue. Thanks for your help, ^ solved my problem.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sami616 picture sami616  路  3Comments

eddeee888 picture eddeee888  路  3Comments

mattfysh picture mattfysh  路  3Comments

rockmandash picture rockmandash  路  3Comments

kentcdodds picture kentcdodds  路  3Comments