From 343010943e3647df83d7db2338f5f3250a25546c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Fri, 4 Sep 2020 23:38:06 +0200 Subject: [PATCH] Fixed an issue with wrapped class components not having a type for the `ref` prop --- .changeset/cyan-apes-join.md | 5 +++ packages/styled/types/base.d.ts | 64 +++++++++++++++++++++++++--- packages/styled/types/tests-base.tsx | 37 +++++++++++++++- 3 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 .changeset/cyan-apes-join.md diff --git a/.changeset/cyan-apes-join.md b/.changeset/cyan-apes-join.md new file mode 100644 index 000000000..c94f11eae --- /dev/null +++ b/.changeset/cyan-apes-join.md @@ -0,0 +1,5 @@ +--- +'@emotion/styled': patch +--- + +Fixed an issue with wrapped class components not having a type for the `ref` prop. diff --git a/packages/styled/types/base.d.ts b/packages/styled/types/base.d.ts index 31c61be2f..50eec2bf4 100644 --- a/packages/styled/types/base.d.ts +++ b/packages/styled/types/base.d.ts @@ -35,8 +35,18 @@ export interface StyledOptions { */ export interface StyledComponent< ComponentProps extends {}, - SpecificComponentProps extends {} = {} -> extends React.FC, ComponentSelector { + SpecificComponentProps extends {} = {}, + JSXProps extends {} = {} +> + extends React.FC, + ComponentSelector { + withComponent>>( + component: C + ): StyledComponent< + ComponentProps & PropsOf, + {}, + { ref?: React.Ref> } + > withComponent>>( component: C ): StyledComponent> @@ -51,7 +61,8 @@ export interface StyledComponent< */ export interface CreateStyledComponent< ComponentProps extends {}, - SpecificComponentProps extends {} = {} + SpecificComponentProps extends {} = {}, + JSXProps extends {} = {} > { /** * @typeparam AdditionalProps Additional props to add to your styled component @@ -64,14 +75,18 @@ export interface CreateStyledComponent< AdditionalProps & { theme: Theme } > > - ): StyledComponent + ): StyledComponent< + ComponentProps & AdditionalProps, + SpecificComponentProps, + JSXProps + > ( template: TemplateStringsArray, ...styles: Array< Interpolation > - ): StyledComponent + ): StyledComponent /** * @typeparam AdditionalProps Additional props to add to your styled component @@ -85,7 +100,11 @@ export interface CreateStyledComponent< AdditionalProps & { theme: Theme } > > - ): StyledComponent + ): StyledComponent< + ComponentProps & AdditionalProps, + SpecificComponentProps, + JSXProps + > } /** @@ -98,6 +117,39 @@ export interface CreateStyledComponent< * @example styled('div')(props => ({ width: props.width }) */ export interface CreateStyled { + < + C extends React.ComponentClass>, + ForwardedProps extends keyof React.ComponentProps< + C + > = keyof React.ComponentProps + >( + component: C, + options: FilteringStyledOptions, ForwardedProps> + ): CreateStyledComponent< + Pick, ForwardedProps> & { + theme?: Theme + as?: React.ElementType + }, + {}, + { + ref?: React.Ref> + } + > + + >>( + component: C, + options?: StyledOptions> + ): CreateStyledComponent< + PropsOf & { + theme?: Theme + as?: React.ElementType + }, + {}, + { + ref?: React.Ref> + } + > + < C extends React.ComponentType>, ForwardedProps extends keyof React.ComponentProps< diff --git a/packages/styled/types/tests-base.tsx b/packages/styled/types/tests-base.tsx index ddae92bf4..027d5b4ca 100644 --- a/packages/styled/types/tests-base.tsx +++ b/packages/styled/types/tests-base.tsx @@ -261,7 +261,6 @@ const StyledClass0 = styled(ReactClassComponent0)({}) declare const ref0_0: (element: ReactClassComponent0 | null) => void declare const ref0_1: (element: ReactClassComponent1 | null) => void declare const ref0_2: (element: HTMLDivElement | null) => void -// $ExpectError ; // $ExpectError ; @@ -272,7 +271,6 @@ const StyledClass1 = StyledClass0.withComponent(ReactClassComponent1) declare const ref1_0: (element: ReactClassComponent1 | null) => void declare const ref1_1: (element: ReactClassComponent0 | null) => void declare const ref1_2: (element: HTMLDivElement | null) => void -// $ExpectError ; // $ExpectError ; @@ -442,3 +440,38 @@ const Section = styled('section')` // $ExpectError ; } + +{ + // simple class ref test + class FixedSizeList extends React.Component { + scrollTo = () => {} + + render() { + return null + } + } + + const StyledList = styled(FixedSizeList)` + color: hotpink; + ` + const listRef = React.useRef(null) + ; +} + +{ + // withComponent class ref test + class FixedSizeList extends React.Component { + scrollTo = () => {} + + render() { + return null + } + } + + const StyledList = styled('li')` + color: hotpink; + ` + const StyledFixedStyleList = StyledList.withComponent(FixedSizeList) + const listRef = React.useRef(null) + ; +}