React Styled-components TypeScript extending styles with props on base style gets TS2769 error

Viewed 912

I am trying to extend a base styled to other styled components and I get a typescript error. I have been able to do this in just pure javascript, am not able to do the same in typescript

base file _Modal.ts

import styled from 'styled-components/macro'

interface I_Modal {
  'background-color': string
  'min-height': string
  'min-width': string
}

const _modal = styled.div<I_Modal>`
  background-color: ${props => props['background-color'] ? props['background-color'] : props.theme.colors.baseColor};
  min-height: ${props => props['min-height'] ? props['min-height'] : '300px'};
  min-width: ${props => props['min-width'] ? props['min-width'] : '200px'}
`

export default _modal

file i am trying to extend the styles to registerModal.ts

import styled from 'styled-components/macro'
import _modal from './_modal'

export const RegisterModal = styled(_modal)`
  background-color: purple;
  height: 300px;
  width: 200px;
`

everything in VSCode says its good, its just not compiling properly image of error

1 Answers

Tips for using styled-components in TypeScript

If the parent is not a specific react component, it is recommended to write it simply as follows.

const Button = styled.button<{primary: boolean}>`
  color: ${({primary}) => primary ? 'skyblue' };
`

Picking can reduce maintenance costs if the component is complex or references the parent props

interface Props {
  primary
  secondary
}

function MyComponent(props: Props) {
  return (
    <div>
      <Button secondary={props.secondary} primary={props.primary}>{props.children}</Button>
    </div>
  )
}

const Button = styled.button<Pick<Props, 'primary' | 'secondary'>>`
  ${({primary, secondary}) => primary ? css`` : secondary ? css`` : css``}
`

Type a constant

It is convenient to type constants such as color and size so that you can see which px is applied when you use them.
const FONT = {
  XXXLARGE: 32,
  XXLARGE: 24,
  XLARGE: 18,
  LARGE: 16,
  MEDIUM: 14,
  BASE: 12,
  SMALL: 11,
  XSMALL: 10,
  TINY: 8,
} as const

const FONT_WEIGHT = {
  NORMAL: 400,
  BOLD: 600,
} as const

const BORDER_RADIUS = 4 as 4

export default {
  FONT,
  FONT_WEIGHT,
  BORDER_RADIUS
}

By doing this, you can check which constant has which px with the suggestion function of the editor. enter image description here

When using css prop

Babel-plugin and css prop enabled by babel macro are extensions of jsx, so if you do nothing, TS will get angry. You can solve it by writing the following in index.d.ts of type root. (Styled-components / cssprop is an extension of react)
import {} from 'styled-components/cssprop'

When using attrs

This has to be a bit cumbersome to write, so you may not use attrs a lot in the first place.
const StyledImg = styled.img.attrs<{ logoSrc: logoSrc }>(
  ({logoSrc}) => ({
    src: logoSrc,
  })
)<{ logoSrc: logoSrc }>
Related