styled-components icon indicating copy to clipboard operation
styled-components copied to clipboard

v6 .attrs() types are broken

Open laboskin opened this issue 1 year ago • 2 comments

Environment

styled-components: 6.0.7 react: 18.2.0 react-dom: 18.2.0 typescript: 5.0.2

Reproduction

https://codesandbox.io/s/styled-component-playground-forked-9fvr9m?file=/src/index.tsx

import type { FC } from "react";
import styled from "styled-components";
import { createRoot } from "react-dom/client";

type ContainerProps = {
  color: string;
};
const Container: FC<ContainerProps> = ({ color }) => {
  return <div style={{ color }} />;
};

const StyledContainer = styled(Container).attrs({ color: 'red' })``;

function App() {
  return <StyledContainer />; // TS Error: "color" props is missing
}

const root = createRoot(document.getElementById("root")!);
root.render(<App />);

Expected Behavior

No TS error, just like in styled-components v5

Actual Behavior

"color" prop is missing, although it was binded inside .attrs(...) call and should not be required

laboskin avatar Aug 22 '23 09:08 laboskin

Not sure if it's exactly related to this issue but you also get a type error with attrs when you use it with an arrow function props parameter even if you explicitly specify the type for the parameter. For example (https://codesandbox.io/s/styled-component-playground-forked-wq6ngr?file=/src/index.tsx):

import styled from "styled-components";
import { createRoot } from "react-dom/client";

type ContainerProps = {
  $test: string;
};

const StyledContainer = styled.div.attrs((p: ContainerProps) => ({
  "test-attr": p.$test
}))<ContainerProps>``;

function App() {
  return <StyledContainer $test="hello">test</StyledContainer>;
}

const root = createRoot(document.getElementById("root")!);
root.render(<App />);

This works in 5.3.9 but in 6.0.7 I get the following type error:

Argument of type '(p: ContainerProps) => { "test-attr": string; }' is not assignable to parameter of type 'Attrs<FastOmit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>'.
  Type '(p: ContainerProps) => { "test-attr": string; }' is not assignable to type '(props: ExecutionContext & FastOmit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>) => ExecutionProps & Partial<...>'.
    Types of parameters 'p' and 'props' are incompatible.
      Property '$test' is missing in type 'ExecutionContext & FastOmit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>' but required in type 'ContainerProps'.ts(2345)
index.tsx(5, 3): '$test' is declared here.

The documentation (https://styled-components.com/docs/basics#attaching-additional-props) doesn't explicitly add the type to the props param but I never got it to work without it even on 5.x.

davidkarlsson avatar Aug 29 '23 11:08 davidkarlsson

This is duplication of https://github.com/styled-components/styled-components/issues/4076

tomfridental1 avatar Oct 26 '23 06:10 tomfridental1