Augmenting the DOMAttributes interface with 'css' causes conflicts
See original GitHub issueemotion
version: 10.0.7react
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
(!).
Issue Analytics
- State:
- Created 5 years ago
- Reactions:24
- Comments:10 (2 by maintainers)
Top GitHub Comments
+1 Also ran into this via storybook
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.