Corey Bruyere
Corey Bruyere

Reputation: 976

How to fix 'Types of property 'color' are incompatible' on Box component using typescript and emotion

I'm attempting to make a general Box react component on a new project. This will be the base of all other components. I'm using styled-system, emotion, and eventually theme-ui to handle themeing and styling of all my components.

My root Box component looks like this:

import styled from '@emotion/styled';
import {
  compose,
  space,
  layout,
  flexbox,
  border,
  position,
  color,
  SpaceProps,
  ColorProps,
  LayoutProps,
  FlexboxProps,
  BorderProps,
  PositionProps,
} from 'styled-system';

export type BoxProps = SpaceProps &
  ColorProps &
  LayoutProps &
  FlexboxProps &
  BorderProps &
  PositionProps;

export const Box = styled.div<BoxProps>(
  {
    boxSizing: 'border-box',
    minWidth: 0,
  },
  compose(space, color, layout, flexbox, border, position)
);

I'm using styled functions along with their associated types from styled-system to create a Box component that accepts space, color, layout, flexbox, border, and position props.

The error I'm getting is happening only with the color prop. Once I remove that I don't get any errors.

The TS error is:

Type 'BoxProps' does not satisfy the constraint 'Pick<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "color">, "color">'.
  Types of property 'color' are incompatible.
    Type 'string | number | symbol | (string | number | symbol | null)[] | { [x: string]: string | number | symbol | undefined; [x: number]: string | number | symbol | undefined; } | null | undefined' is not assignable to type 'string | undefined'.
      Type 'null' is not assignable to type 'string | undefined'.ts(2344)

This seems to only be an issue when moving from styled-components to emotion, so I'm not sure if there's something I'm missing to properly utilize emotion's types?

Upvotes: 5

Views: 3423

Answers (2)

Moa
Moa

Reputation: 1566

You could also Omit conflicting HTMLAttributes from your Props.

As in:

interface Props {
  color?: string
}

// omit any prop in React.HTMLAttributes that is declared in Props
type NativeAttrs = Omit<React.HTMLAttributes<any>, keyof Props>

export type ButtonProps = Props & NativeAttrs

Upvotes: 0

mavlikwowa
mavlikwowa

Reputation: 71

If you have errors with types "type" and "as" you should redefine these types before insert these in styled components. Perhaps, if you try to rewrite your props, it will help. My example:

/* Button component */
const Button: React.FC<ButtonProps> = ({
  isLoading,
  children,
  // should redefine this types, because React.HTMLProps<HTMLButtonElement> has incompatible similar types
  type = 'button',
  as = undefined,
  ...props
}: ButtonProps, ...others) => {
  return (
    <StyledButton {...props} {...others}>
      {isLoading ? 'Loading...' : children}
    </StyledButton>
  );
};

export default Button;

Upvotes: 1

Related Questions