Home > Net >  How to get StyledComponent's type in intellisense?
How to get StyledComponent's type in intellisense?

Time:09-01

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.

  • Related