As per styled-components v4, .extend
is deprecated, the correct way to extend, or compose components is:
const ButtonA = styled('button')`color: ${props => props.color};`
const ButtonB = styled(ButtonA)`background: 'white';`
However I can't find the correct way to do this with TS, as I get some errors, for example:
import styled from "styled-components";
// Let's create ButtonA
type ButtonAProps = { a: string };
const ButtonA = styled<ButtonAProps, "button">("button")`
color: ${props => props.a};
`;
// So, here is what I've tried
// Fail #1
// =======
type ButtonBProps = { b: string };
const ButtonB = styled<ButtonBProps, ButtonAProps>(ButtonA)`
background: ${props => props.b};
`; // Here I get autocompletion only for B props :(
const Test = () => <ButtonB a="something" />; // And here I get autocompletion only for A props :(
// Fail #2
// =======
type ButtonBProps = { b: string } & ButtonAProps;
const ButtonB = styled<ButtonBProps, ButtonAProps>(ButtonA)`
background: ${props => props.b};
`; // Here I get autocompletion for A & B props, good!
const Test = () => <ButtonB a="something" />; // Here I still get autocompletion only for A props :(
// Fail #3
// =======
type ButtonBProps = { b: string } & ButtonAProps;
const ButtonB = styled<ButtonBProps, ButtonBProps>(ButtonA)` // Property 'b' is missing in type 'ButtonAProps', of course
background: ${props => props.b};
`; // Here I get "props has implicitly any type"
const Test = () => <ButtonB />; // Here I don't get any type checking at all
Seems to be almost there, but can't figure it out.
Any advices? Thank you!
We need to install some dependencies because styled-components doesn't come with create-react-app. This installs the styled-components types for TypeScript as a dev dependency. There's a styled-components extension for VS Code that makes it look like we're typing actual CSS even though it's a TypeScript file.
Marking styled-components as external in your package dependencies. Moving styled-components to devDependencies will guarantee that it wouldn't be installed along with your library (npm install or yarn add will ignore devDependencies when a library is installed).
You can override an existing styled-components component by passing it to the styled() constructor/wrapper. For example, suppose you have the following styled button element: const Button = styled.
As of September 2019, the following code also works:
// First extend ButtonAProps with an additional prop
interface ButtonBProps extends ButtonAProps {
b:string;
}
// ButtonB Component
const ButtonB = styled(ButtonA)<ButtonBProps>`
background: ${props => props.b};
`;
This seems to work for me:
type ButtonBProps = { b: string };
const ButtonB = styled<ButtonAProps>(ButtonA)<ButtonBProps>`
background: ${props => props.b};
`;
const Test = () => <ButtonB a="something" b="somethingelse" />;
The @types/styled-components
declarations are hard to understand (with unhelpful type parameter names P
, T
, O
, U
) and apparently undocumented, so I can't be sure this is the intended approach. I found a related issue, but it doesn't seem to confirm this approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With