Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript issue with styled-component's "css" prop and Storybook

I'm having issues with enabling styled-component's css prop in TypeScript as soon as I import something from Storybook, because Storybook depends on @emotion/core, whose type declaration defines Emotion's own css prop. The error stems from the fact that the two css prop types being incompatible.

I'm familiar with the recommended way of enabling the css prop in TypeScript (including the answer on Stack Overflow), as well as suggestions on how to handle the Storybook problem explained above.

This is the application code, index.tsx:

import React from 'react'
import { css } from 'styled-components'

export default function App() {
  return (
    <h1
      css={css`
        color: red;
      `}
    >
      Hello world!
    </h1>
  )
}

and this is the type declaration, styled-components.d.ts, which contains the attempted fix:

import { CSSProp } from "styled-components";

// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31245#issuecomment-780019806

declare module 'react' {
  interface DOMAttributes<T> {
    css?: CSSProp
  }
}
declare global {
  namespace JSX {
    interface IntrinsicAttributes {
      css?: CSSProp
    }
  }
}

This works until I import something in index.tsx from Storybook which imports @emotion/core, for example:

import { storiesOf } from '@storybook/react'
// ...

Then TypeScript fails with the following errors:

index.tsx:8:7 - error TS2322: Type 'FlattenSimpleInterpolation' is not assignable to type 'InterpolationWithTheme<any>'.
  Type 'readonly SimpleInterpolation[]' is not assignable to type 'ObjectInterpolation<undefined>'.
    Types of property 'filter' are incompatible.
      Type '{ <S extends SimpleInterpolation>(predicate: (value: SimpleInterpolation, index: number, array: readonly SimpleInterpolation[]) => value is S, thisArg?: any): S[]; (predicate: (value: SimpleInterpolation, index: number, array: readonly SimpleInterpolation[]) => unknown, thisArg?: any): SimpleInterpolation[]; }' is not assignable to type 'string | string[] | undefined'.
        Type '{ <S extends SimpleInterpolation>(predicate: (value: SimpleInterpolation, index: number, array: readonly SimpleInterpolation[]) => value is S, thisArg?: any): S[]; (predicate: (value: SimpleInterpolation, index: number, array: readonly SimpleInterpolation[]) => unknown, thisArg?: any): SimpleInterpolation[]; }' is missing the following properties from type 'string[]': pop, push, concat, join, and 27 more.

8       css={css`
        ~~~

  node_modules/@emotion/core/types/index.d.ts:84:5
    84     css?: InterpolationWithTheme<any>
           ~~~
    The expected type comes from property 'css' which is declared here on type 'DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>'

styled-components.d.ts:7:5 - error TS2717: Subsequent property declarations must have the same type.  Property 'css' must be of type 'InterpolationWithTheme<any>', but here has type 'CSSProp<any> | undefined'.

7     css?: CSSProp
      ~~~

  node_modules/@emotion/core/types/index.d.ts:84:5
    84     css?: InterpolationWithTheme<any>
           ~~~
    'css' was also declared here.

styled-components.d.ts:13:7 - error TS2717: Subsequent property declarations must have the same type.  Property 'css' must be of type 'InterpolationWithTheme<any>', but here has type 'CSSProp<any> | undefined'.

13       css?: CSSProp
         ~~~

  node_modules/@emotion/core/types/index.d.ts:96:7
    96       css?: InterpolationWithTheme<any>
             ~~~
    'css' was also declared here.

Here's the CodeSandbox created from this repository which reproduces this issue.

like image 377
silvenon Avatar asked Nov 17 '25 13:11

silvenon


1 Answers

According to the documentation for the styled-components library, it seems that you should be importing style rather than css.

I created an example showing how to do this:
https://codesandbox.io/s/react-typescript-forked-1xkww4?file=/src/App.tsx

Alternatively, you could try casting css as something else, although I'm not sure it would help with the type definition conflict you're having.

import { css as StyledCss } from 'styled-components';

Hopefully this helps.

like image 104
M Polak Avatar answered Nov 20 '25 03:11

M Polak



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!