I have created a function which takes a component and returns a Styled component of that
import styled from 'styled-components';
const withStyled = (Component, styles) => {
const StyledComponent = styled(Component)`
${styles}
`;
return StyledComponent;
};
export default withStyled;
I am using this withStyled function as below
import cx from 'classnames';
import React from 'react';
import withStyled from '../../../hoc/withStyled';
import styles from './Paragraph.style';
interface Props {
className: string;
sizeVariant: string;
children: string;
}
const Paragraph = (props: Props) => {
const { children, className, ...extraProps } = props;
return (
<p className={cx('paragraph', className)} {...extraProps}>
{children}
</p>
);
};
const StyledParagraph = withStyled(Paragraph, styles);
export default StyledParagraph;
But when I am using my Paragraph component, VS code intellisense is not showing me suggestions related to props This is because withStyled function is returning me a new component and my original component's types are lost in the process.
Is there a way to get the original types in StyledComponent too?
CodePudding user response:
Have you looked at this: https://github.com/styled-components/vscode-styled-components
"The styled-components extension adds highlighting and IntelliSense for styled-component template strings in JavaScript and TypeScript."
CodePudding user response:
TLDR
function withStyled<
T extends keyof JSX.IntrinsicElements | React.ComponentType<any>
>(component: T, styles: string): T {
return styled(component)`${styles}`;
}
Stackblitz: https://stackblitz.com/edit/react-ts-rbqxgt?file=App.tsx
The @types/styled-components
package seems to be a bit busted, since the StyledComponent
type just resolves to any
. This is what I get from Intellisense:
type StyledComponent<
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
T extends object,
O extends object = {},
A extends string | number | symbol = never
> = any;
You can use generics to just return the same component type. FC stands for Function Component.
function withStyled<T>(component: React.FC<T>, styles: string): React.FC<T> {
return styled(component)`${styles}`;
}
An arrow function requires you to write <T extends Object>
or <T,_>
instead of just <T>
else it clashes with JSX.
const withStyled = <T extends Object>(
Component: React.FC<T>,
styles: string
): React.FC<T> => styled(Component)`${styles}`;
Then, this line:
const StyledParagraph = withStyled(Paragraph, styles);
Produces this intellisense:
const StyledParagraph: React.FC<Props>
And you will get type errors as normal.
To allow for passing any acceptable types, not just function components, you can use T extends keyof JSX.IntrinsicElements | React.ComponentType<any>
and just return the same type, as shown in the TLDR.