Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Augmenting the DOMAttributes interface with 'css' causes conflicts #1257

Closed
Jessidhia opened this issue Mar 5, 2019 · 10 comments
Closed

Augmenting the DOMAttributes interface with 'css' causes conflicts #1257

Jessidhia opened this issue Mar 5, 2019 · 10 comments
Milestone

Comments

@Jessidhia
Copy link

Jessidhia commented Mar 5, 2019

  • emotion version: 10.0.7
  • react version: 16.8.3

Relevant code:

// NOTE: the code doesn't actually use emotion at all,
// it's an indirect devDependency; but if emotion's types are loaded at all,
// it causes conflicts.
import {} from '@emotion/core'
import styled from 'styled-components'
/// <reference types="styled-components/cssprop"/>

// If I use React.ComponentPropsWithoutRef<'a'> instead there is no conflict,
// but the component I am trying to use does use AnchorHTMLAttributes
interface Props extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
  // the foo doesn't matter, it's just to demonstrate object rest
  foo: boolean
}

export default function WrappedLink({ foo, ...props }: Props) {
  return <A {...props} />
}

// the style doesn't matter
const A = styled.a``

What you did:

In a project that already used styled-components, @emotion/core started being loaded as an indirect devDependency (@storybook/theming, to be more specific).

What happened:

The combination of an augmented React.DOMAttributes with a double-augmented JSX.Attributes is breaking pass-through of the props because the React.DOMAttributes makes the component think it can receive css as a prop.

Type '{ download?: any; href?: string | undefined; hrefLang?: string | undefined; media?: string | undefined; rel?: string | undefined; target?: string | undefined; type?: string | undefined; ... 251 more ...; css?: InterpolationWithTheme<...>; }' is not assignable to type '{ className?: string | undefined; download?: any; href?: string | undefined; hrefLang?: string | undefined; media?: string | undefined; rel?: string | undefined; target?: string | undefined; ... 253 more ...; key?: string | ... 1 more ... | undefined; }'.
  Types of property 'css' are incompatible.
    Type 'InterpolationWithTheme<any>' is not assignable to type 'string | (string & ComponentSelector) | (string & { name: string; styles: string; anim: number; toString: () => string; }) | (string & SerializedStyles) | (string & ArrayInterpolation<undefined>) | ... 12 more ... | undefined'.
      Type 'null' is not assignable to type 'string | (string & ComponentSelector) | (string & { name: string; styles: string; anim: number; toString: () => string; }) | (string & SerializedStyles) | (string & ArrayInterpolation<undefined>) | ... 12 more ... | undefined'.

Reproduction:

CodeSandbox can't typecheck, even in typescript sandboxes :(

Problem description:

@emotion/core unconditionally augments both React.DOMAttributes and JSX.Attribute, but ideally such augmentation should be optional to avoid this conflict.

Suggested solution:

@types/styled-components made it optional by splitting just the augmentation itself into a separate file, and you can request it by adding "styled-components/cssprop" to your tsconfig.json's compilerOptions.types, using a triple-slash reference (only needed once, on any file that's in the project) as in the above sample, or using an empty import (also only needed once).

The augmentation of React.DOMAttributes is technically unnecessary, augmenting React.Attributes is sufficient for all JSX use cases (JSX.Attributes inherits from React.Attributes). The only thing it makes possible is receiving css as a prop, which you can't, even with / especially with the jsx pragma.

The added advantage of making the augmentation optional is that it makes it possible for the user to augment it with a more specific type -- perhaps InterpolationWithTheme<MyTheme>, for example.


EDIT: This also, of course, affects actual uses of css with the styled-components css function, as it becomes impossible to fulfill the type. The only workarounds I can do until this is fixed is to locally augment the css prop in both interfaces with any (!).

@nathanbirrell
Copy link

+1 Also ran into this via storybook

@jvgomg
Copy link

jvgomg commented Oct 28, 2019

The emotion css prop type coming with Storybook brought me here too. I've managed to fix this for myself by adding @emotion/core types to a .yarnclean file.

echo @emotion/core/types >> .yarnclean
yarn

@smeijer
Copy link

smeijer commented May 29, 2020

Thanks @jvgreenaway! That fix works just fine.

For those that are, like me, not using yarn. He's just deleting the file directly after install. So a pm postinstall hook could do the same:

"scripts": {
  "postinstall": "rimraf node_modules/@emotion/core/types"
}

@Andarist Andarist mentioned this issue Jul 27, 2020
2 tasks
@Andarist
Copy link
Member

A fix for this has been just merged into v11 line: #1941

@mavlikwowa
Copy link

mavlikwowa commented Jan 2, 2021

If you have errors with types "type" and "as" you should redefine this types before intert these in styled components. Perhaps, if you try to rewrite css-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;

@jgoux
Copy link

jgoux commented Mar 12, 2021

Hello all,

I want to point out that this conflict still exist when trying to use a component styled with https://github.com/modulz/stitches in the context of storybook :

image

The only solution right now is to add @emotion/core/types to .yarnclean when using storybook.

@Andarist
Copy link
Member

This has been fixed in v11 - @emotion/core is a package only available in v10.

@uoon-dev
Copy link

uoon-dev commented Apr 1, 2021

Hello all,

I want to point out that this conflict still exist when trying to use a component styled with https://github.com/modulz/stitches in the context of storybook :

image

The only solution right now is to add @emotion/core/types to .yarnclean when using storybook.

You're right. Storybook v6 references @emotion/core v10 as dependency that has global css type yet, and it occurs type error if we pass css style of object. it conflicts with @emotion/react v11. If you use storybook v6, the only solution is to remove @emotion/core/types.

@tmikeschu
Copy link

tmikeschu commented Apr 14, 2021

The emotion css prop type coming with Storybook brought me here too. I've managed to fix this for myself by adding @emotion/core types to a .yarnclean file.

echo @emotion/core/types >> .yarnclean
yarn

I also had to add @storybook/theming/node_modules/@emotion/core/types to .yarnclean.

stuarthendren added a commit to commitd/components that referenced this issue May 16, 2021
Causes conflict with stitches, This is fixed in later emotion but storybook currently still on v10.
See  emotion-js/emotion#1257
@IAmNatch
Copy link

For those using Yarn V2 (Berry), there is no longer a .yarnclean file or yarn clean command.

Instead, I needed to create a patch-file, which applies automatically on install.
https://yarnpkg.com/cli/patch

I used the following method:

  1. yarn patch @emotion/core
  2. Open the temporary folder which is created for your patch, and delete the types folder
  3. yarn patch-commit -s
  4. The auto generated resolution didn't match the version required, so I removed the version to ensure that this patch would be used:
// old
"resolutions": {
		"@emotion/core@10.1.1": "patch:@emotion/core@npm:10.1.1#.yarn/patches/@emotion-core-npm-10.1.1-f084e0eeac"
	}

// new
"resolutions": {
		"@emotion/core": "patch:@emotion/core@npm:10.1.1#.yarn/patches/@emotion-core-npm-10.1.1-f084e0eeac"

Hope this helps until the next major version!

ericgio pushed a commit to ericgio/react-bootstrap-typeahead that referenced this issue Mar 30, 2022
There is a known issue with storybook that the @emotion/core dependency augments
the React `HTMLAttributes` with an additional `css` property. This causes the
compiled types of react-bootstrap-typeahead to include that attribute as well,
which in turns breaks Typescript compilation of projects using it.

See: emotion-js/emotion#1257 (comment)
scottjudy added a commit to scottjudy/react-bootstrap-typeahead that referenced this issue Jun 20, 2023
There is a known issue with storybook that the @emotion/core dependency augments
the React `HTMLAttributes` with an additional `css` property. This causes the
compiled types of react-bootstrap-typeahead to include that attribute as well,
which in turns breaks Typescript compilation of projects using it.

See: emotion-js/emotion#1257 (comment)
alexy82 added a commit to alexy82/react-bootstrap-typeahead that referenced this issue Jul 25, 2023
There is a known issue with storybook that the @emotion/core dependency augments
the React `HTMLAttributes` with an additional `css` property. This causes the
compiled types of react-bootstrap-typeahead to include that attribute as well,
which in turns breaks Typescript compilation of projects using it.

See: emotion-js/emotion#1257 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants