New error: Type of property 'defaultProps' circularly references itself in mapped type

See original GitHub issue

https://github.com/nteract/nteract/blob/af734c46893146c617308f4ae1e40bf267e8875f/packages/connected-components/src/header-editor/styled.ts#L24

packages/connected-components/src/header-editor/styled.ts:24:34 - error TS2615: Type of property 'defaultProps' circularly references itself in mapped type 'Pick<ForwardRefExoticComponent<Pick<Pick<any, Exclude<keyof ReactDefaultizedProps<StyledComponentInnerComponent<WithC>, ComponentPropsWithRef<StyledComponentInnerComponent<WithC>>>, StyledComponentInnerAttrs<...> | ... 1 more ... | StyledComponentInnerAttrs<...>> | Exclude<...> | Exclude<...> | Exclude<...>> & Parti...'.

24 export const EditableAuthorTag = styled(AuthorTag)`
                                    ~~~~~~~~~~~~~~~~~

https://github.com/nteract/nteract/blob/af734c46893146c617308f4ae1e40bf267e8875f/packages/presentational-components/src/components/prompt.tsx#L85

Also, I’m seeing each of these errors printed twice.

To repro:

  1. yarn
  2. tsc -b -f

Note that it fails with a different (apparently unrelated) error in 3.8.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:48
  • Comments:23

github_iconTop GitHub Comments

245reactions
lukasklcommented, Jun 29, 2020

Not sure if that applies for all of us, but it seems that this error appears using typescript@^3.9.0 (particularly after this PR https://github.com/microsoft/TypeScript/pull/36696).

This breaking change was mitigated by updating @types/styled-components https://github.com/DefinitelyTyped/DefinitelyTyped/pull/42619

However, this fix was deployed at v5.0.1 of @types/styled-components which covers styled-components@^5.0.0 but, nothing has been deployed for earlier versions (e.g. what would cover styled-components@^4.0.0)

So if you are using styled-components@^5.0.0 simply run

yarn upgrade @types/styled-components --latest
# or
npm install @types/styled-components@latest

if you are using styled-components@^4.0.0, well then it is more difficult for now, as in essence @types/styled-components should be updated.

However, as a temporary fix it is possible to remove @types/styled-components from the project, copy styled-components.d.ts file from @types/styled-components@^4.0.0 to your project and make the same fix as in https://github.com/DefinitelyTyped/DefinitelyTyped/pull/42619 e.g.:

example content of styled-components.d.ts
// forward declarations
declare global {
  namespace NodeJS {
      // tslint:disable-next-line:no-empty-interface
      interface ReadableStream {}
  }
}

declare module 'styled-components' {

  import * as CSS from "csstype";
  import * as React from "react";
  import * as hoistNonReactStatics from 'hoist-non-react-statics';

  export type CSSProperties = CSS.Properties<string | number>;

  export type CSSPseudos = { [K in CSS.Pseudos]?: CSSObject };

  export interface CSSObject extends CSSProperties, CSSPseudos {
    [key: string]: CSSObject | string | number | undefined;
  }

  export type CSSKeyframes = object & { [key: string]: CSSObject };

  export interface ThemeProps<T> {
    theme: T;
  }

  export type ThemedStyledProps<P, T> = P & ThemeProps<T>;
  export type StyledProps<P> = ThemedStyledProps<P, AnyIfEmpty<DefaultTheme>>;

  // Any prop that has a default prop becomes optional, but its type is unchanged
  // Undeclared default props are augmented into the resulting allowable attributes
  // If declared props have indexed properties, ignore default props entirely as keyof gets widened
  // Wrap in an outer-level conditional type to allow distribution over props that are unions
  type Defaultize<P, D> = P extends any
    ? string extends keyof P ? P :
        & Pick<P, Exclude<keyof P, keyof D>>
        & Partial<Pick<P, Extract<keyof P, keyof D>>>
        & Partial<Pick<D, Exclude<keyof D, keyof P>>>
    : never;

  type ReactDefaultizedProps<C, P> = C extends { defaultProps: infer D; }
    ? Defaultize<P, D>
    : P;

  export type StyledComponentProps<
    // The Component from whose props are derived
    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
    // The Theme from the current context
    T extends object,
    // The other props added by the template
    O extends object,
    // The props that are made optional by .attrs
    A extends keyof any
  > =
    // Distribute O if O is a union type
    O extends object
    ? WithOptionalTheme<
          Omit<ReactDefaultizedProps<C, React.ComponentPropsWithRef<C>> & O, A> &
              Partial<Pick<React.ComponentPropsWithRef<C> & O, A>>,
          T
      > &
          WithChildrenIfReactComponentClass<C>
    : never;

  // Because of React typing quirks, when getting props from a React.ComponentClass,
  // we need to manually add a `children` field.
  // See https://github.com/DefinitelyTyped/DefinitelyTyped/pull/31945
  // and https://github.com/DefinitelyTyped/DefinitelyTyped/pull/32843
  type WithChildrenIfReactComponentClass<
    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>
  > = C extends React.ComponentClass<any> ? { children?: React.ReactNode } : {};

  type StyledComponentPropsWithAs<
    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
    T extends object,
    O extends object,
    A extends keyof any
  > = StyledComponentProps<C, T, O, A> & { as?: C, forwardedAs?: C };

  export type FalseyValue = undefined | null | false;
  export type Interpolation<P> =
    | InterpolationValue
    | InterpolationFunction<P>
    | FlattenInterpolation<P>;
  // cannot be made a self-referential interface, breaks WithPropNested
  // see https://github.com/microsoft/TypeScript/issues/34796
  export type FlattenInterpolation<P> = ReadonlyArray<Interpolation<P>>;
  export type InterpolationValue =
    | string
    | number
    | FalseyValue
    | Keyframes
    | StyledComponentInterpolation
    | CSSObject;
  export type SimpleInterpolation =
    | InterpolationValue
    | FlattenSimpleInterpolation;
  export type FlattenSimpleInterpolation = ReadonlyArray<SimpleInterpolation>;

  export type InterpolationFunction<P> = (props: P) => Interpolation<P>;

  type Attrs<P, A extends Partial<P>, T> =
    | ((props: ThemedStyledProps<P, T>) => A)
    | A;
  type DeprecatedAttrs<P, A extends Partial<P>, T> = {
    [K in keyof A]: ((props: ThemedStyledProps<P, T>) => A[K]) | A[K]
  };

  export type ThemedGlobalStyledClassProps<P, T> = WithOptionalTheme<P, T> & {
    suppressMultiMountWarning?: boolean;
  };

  export interface GlobalStyleComponent<P, T>
    extends React.ComponentClass<ThemedGlobalStyledClassProps<P, T>> {}

  // remove the call signature from StyledComponent so Interpolation can still infer InterpolationFunction
  type StyledComponentInterpolation =
    | Pick<
          StyledComponentBase<any, any, any, any>,
          keyof StyledComponentBase<any, any>
      >
    | Pick<
          StyledComponentBase<any, any, any>,
          keyof StyledComponentBase<any, any>
      >;

  // abuse Pick to strip the call signature from ForwardRefExoticComponent
  type ForwardRefExoticBase<P> = Pick<
    React.ForwardRefExoticComponent<P>,
    keyof React.ForwardRefExoticComponent<any>
  >;

  // extracts React defaultProps
  type ReactDefaultProps<C> = C extends { defaultProps: infer D; } ? D : never;

  // any doesn't count as assignable to never in the extends clause, and we default A to never
  export type AnyStyledComponent =
    | StyledComponent<any, any, any, any>
    | StyledComponent<any, any, any>;

  export type StyledComponent<
    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
    T extends object,
    O extends object = {},
    A extends keyof any = never
  > = // the "string" allows this to be used as an object key
    // I really want to avoid this if possible but it's the only way to use nesting with object styles...
    string & StyledComponentBase<C, T, O, A> & hoistNonReactStatics.NonReactStatics<C extends React.ComponentType<any> ? C : never>;

  export interface StyledComponentBase<
    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
    T extends object,
    O extends object = {},
    A extends keyof any = never
  > extends ForwardRefExoticBase<StyledComponentProps<C, T, O, A>> {
    // add our own fake call signature to implement the polymorphic 'as' prop
    (
        props: StyledComponentProps<C, T, O, A> & { as?: never, forwardedAs?: never }
      ): React.ReactElement<StyledComponentProps<C, T, O, A>>;
    <AsC extends keyof JSX.IntrinsicElements | React.ComponentType<any> = C>(
      props: StyledComponentPropsWithAs<AsC, T, O, A>
    ): React.ReactElement<StyledComponentPropsWithAs<AsC, T, O, A>>;

    withComponent<WithC extends AnyStyledComponent>(
        component: WithC
    ): StyledComponent<
        StyledComponentInnerComponent<WithC>,
        T,
        O & StyledComponentInnerOtherProps<WithC>,
        A | StyledComponentInnerAttrs<WithC>
    >;
    withComponent<
        WithC extends keyof JSX.IntrinsicElements | React.ComponentType<any>
    >(
        component: WithC
    ): StyledComponent<WithC, T, O, A>;
  }

  export interface ThemedStyledFunctionBase<
    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
    T extends object,
    O extends object = {},
    A extends keyof any = never
  > {
    (first: TemplateStringsArray): StyledComponent<C, T, O, A>;
    (
        first:
            | TemplateStringsArray
            | CSSObject
            | InterpolationFunction<
                  ThemedStyledProps<StyledComponentPropsWithRef<C> & O, T>
              >,
        ...rest: Array<
            Interpolation<
                ThemedStyledProps<StyledComponentPropsWithRef<C> & O, T>
            >
        >
    ): StyledComponent<C, T, O, A>;
    <U extends object>(
        first:
            | TemplateStringsArray
            | CSSObject
            | InterpolationFunction<
                  ThemedStyledProps<StyledComponentPropsWithRef<C> & O & U, T>
              >,
        ...rest: Array<
            Interpolation<
                ThemedStyledProps<StyledComponentPropsWithRef<C> & O & U, T>
            >
        >
    ): StyledComponent<C, T, O & U, A>;
  }

  export interface ThemedStyledFunction<
    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
    T extends object,
    O extends object = {},
    A extends keyof any = never
  > extends ThemedStyledFunctionBase<C, T, O, A> {
    // Fun thing: 'attrs' can also provide a polymorphic 'as' prop
    // My head already hurts enough so maybe later...
    attrs<
        U,
        NewA extends Partial<StyledComponentPropsWithRef<C> & U> & {
            [others: string]: any;
        } = {}
    >(
        attrs: Attrs<StyledComponentPropsWithRef<C> & U, NewA, T>
    ): ThemedStyledFunction<C, T, O & NewA, A | keyof NewA>;
    // Only this overload is deprecated
    // tslint:disable:unified-signatures
    /** @deprecated Prefer using the new single function style, to be removed in v5 */
    attrs<
        U,
        NewA extends Partial<StyledComponentPropsWithRef<C> & U> & {
            [others: string]: any;
        } = {}
    >(
        attrs: DeprecatedAttrs<StyledComponentPropsWithRef<C> & U, NewA, T>
    ): ThemedStyledFunction<C, T, O & NewA, A | keyof NewA>;
    // tslint:enable:unified-signatures
  }

  export type StyledFunction<
    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>
  > = ThemedStyledFunction<C, any>;

  type ThemedStyledComponentFactories<T extends object> = {
    [TTag in keyof JSX.IntrinsicElements]: ThemedStyledFunction<TTag, T>
  };

  export type StyledComponentInnerComponent<
    C extends React.ComponentType<any>
  > = C extends StyledComponent<infer I, any, any, any> ? I :
    C extends StyledComponent<infer I, any, any> ? I :
    C;
  export type StyledComponentPropsWithRef<
    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>
  > = C extends AnyStyledComponent
    ? React.ComponentPropsWithRef<StyledComponentInnerComponent<C>>
    : React.ComponentPropsWithRef<C>;
  export type StyledComponentInnerOtherProps<C extends AnyStyledComponent> =
    C extends StyledComponent<any, any, infer O, any> ? O :
    C extends StyledComponent<any, any, infer O> ? O :
    never;
  export type StyledComponentInnerAttrs<
    C extends AnyStyledComponent
  > = C extends StyledComponent<any, any, any, infer A> ? A : never;

  export interface ThemedBaseStyledInterface<T extends object>
    extends ThemedStyledComponentFactories<T> {
    <C extends AnyStyledComponent>(component: C): ThemedStyledFunction<
        StyledComponentInnerComponent<C>,
        T,
        StyledComponentInnerOtherProps<C>,
        StyledComponentInnerAttrs<C>
    >;
    <C extends keyof JSX.IntrinsicElements | React.ComponentType<any>>(
        // unfortunately using a conditional type to validate that it can receive a `theme?: Theme`
        // causes tests to fail in TS 3.1
        component: C
    ): ThemedStyledFunction<C, T>;
  }

  export type ThemedStyledInterface<T extends object> = ThemedBaseStyledInterface<
    AnyIfEmpty<T>
  >;
  export type StyledInterface = ThemedStyledInterface<DefaultTheme>;

  export interface BaseThemedCssFunction<T extends object> {
    (
        first: TemplateStringsArray | CSSObject,
        ...interpolations: SimpleInterpolation[]
    ): FlattenSimpleInterpolation;
    (
        first:
            | TemplateStringsArray
            | CSSObject
            | InterpolationFunction<ThemedStyledProps<{}, T>>,
        ...interpolations: Array<Interpolation<ThemedStyledProps<{}, T>>>
    ): FlattenInterpolation<ThemedStyledProps<{}, T>>;
    <P extends object>(
        first:
            | TemplateStringsArray
            | CSSObject
            | InterpolationFunction<ThemedStyledProps<P, T>>,
        ...interpolations: Array<Interpolation<ThemedStyledProps<P, T>>>
    ): FlattenInterpolation<ThemedStyledProps<P, T>>;
  }

  export type ThemedCssFunction<T extends object> = BaseThemedCssFunction<
    AnyIfEmpty<T>
  >;

  // Helper type operators
  type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
  type WithOptionalTheme<P extends { theme?: T }, T> = Omit<P, "theme"> & {
    theme?: T;
  };
  type AnyIfEmpty<T extends object> = keyof T extends never ? any : T;

  export interface ThemedStyledComponentsModule<
    T extends object,
    U extends object = T
  > {
    default: ThemedStyledInterface<T>;

    css: ThemedCssFunction<T>;

    // unfortunately keyframes can't interpolate props from the theme
    keyframes(
        strings: TemplateStringsArray | CSSKeyframes,
        ...interpolations: SimpleInterpolation[]
    ): Keyframes;

    createGlobalStyle<P extends object = {}>(
        first:
            | TemplateStringsArray
            | CSSObject
            | InterpolationFunction<ThemedStyledProps<P, T>>,
        ...interpolations: Array<Interpolation<ThemedStyledProps<P, T>>>
    ): GlobalStyleComponent<P, T>;

    withTheme: WithThemeFnInterface<T>;
    ThemeProvider: ThemeProviderComponent<T, U>;
    ThemeConsumer: React.Consumer<T>;
    ThemeContext: React.Context<T>;

    // This could be made to assert `target is StyledComponent<any, T>` instead, but that feels not type safe
    isStyledComponent: typeof isStyledComponent;

    ServerStyleSheet: typeof ServerStyleSheet;
    StyleSheetManager: typeof StyleSheetManager;
  }

  declare const styled: StyledInterface;

  export const css: ThemedCssFunction<DefaultTheme>;

  export type BaseWithThemeFnInterface<T extends object> = <
    C extends React.ComponentType<any>
  >(
    // this check is roundabout because the extends clause above would
    // not allow any component that accepts _more_ than theme as a prop
    component: React.ComponentProps<C> extends { theme?: T } ? C : never
  ) => React.ForwardRefExoticComponent<
    WithOptionalTheme<React.ComponentPropsWithRef<C>, T>
  >;
  export type WithThemeFnInterface<T extends object> = BaseWithThemeFnInterface<
    AnyIfEmpty<T>
  >;
  export const withTheme: WithThemeFnInterface<DefaultTheme>;

  /**
  * This interface can be augmented by users to add types to `styled-components`' default theme
  * without needing to reexport `ThemedStyledComponentsModule`.
  */
  // Unfortunately, there is no way to write tests for this
  // as any augmentation will break the tests for the default case (not augmented).
  // tslint:disable-next-line:no-empty-interface
  export interface DefaultTheme {}

  export interface ThemeProviderProps<T extends object, U extends object = T> {
    children?: React.ReactNode;
    theme: T | ((theme: U) => T);
  }
  export type BaseThemeProviderComponent<
    T extends object,
    U extends object = T
  > = React.ComponentClass<ThemeProviderProps<T, U>>;
  export type ThemeProviderComponent<
    T extends object,
    U extends object = T
  > = BaseThemeProviderComponent<AnyIfEmpty<T>, AnyIfEmpty<U>>;
  export const ThemeProvider: ThemeProviderComponent<AnyIfEmpty<DefaultTheme>>;
  // NOTE: this technically starts as undefined, but allowing undefined is unhelpful when used correctly
  export const ThemeContext: React.Context<AnyIfEmpty<DefaultTheme>>;
  export const ThemeConsumer: typeof ThemeContext["Consumer"];

  export interface Keyframes {
    getName(): string;
  }

  export function keyframes(
    strings: TemplateStringsArray | CSSKeyframes,
    ...interpolations: SimpleInterpolation[]
  ): Keyframes;

  export function createGlobalStyle<P extends object = {}>(
    first:
        | TemplateStringsArray
        | CSSObject
        | InterpolationFunction<ThemedStyledProps<P, DefaultTheme>>,
    ...interpolations: Array<Interpolation<ThemedStyledProps<P, DefaultTheme>>>
  ): GlobalStyleComponent<P, DefaultTheme>;

  export function isStyledComponent(
    target: any
  ): target is StyledComponent<any, any>;

  export class ServerStyleSheet {
    collectStyles(
        tree: React.ReactNode
    ): React.ReactElement<{ sheet: ServerStyleSheet }>;

    getStyleTags(): string;
    getStyleElement(): Array<React.ReactElement<{}>>;
    interleaveWithNodeStream(
        readableStream: NodeJS.ReadableStream
    ): NodeJS.ReadableStream;
    readonly instance: this;
    seal(): void;
  }

  type StyleSheetManagerProps =
    | {
          sheet: ServerStyleSheet;
          target?: never;
      }
    | {
          sheet?: never;
          target: HTMLElement;
      };

  export class StyleSheetManager extends React.Component<
    StyleSheetManagerProps
  > {}

  /**
  * The CSS prop is not declared by default in the types as it would cause 'css' to be present
  * on the types of anything that uses styled-components indirectly, even if they do not use the
  * babel plugin.
  *
  * You can load a default declaration by using writing this special import from
  * a typescript file. This module does not exist in reality, which is why the {} is important:
  *
  * ```ts
  * import {} from 'styled-components/cssprop'
  * ```
  *
  * Or you can declare your own module augmentation, which allows you to specify the type of Theme:
  *
  * ```ts
  * import { CSSProp } from 'styled-components'
  *
  * interface MyTheme {}
  *
  * declare module 'react' {
  *   interface Attributes {
  *     css?: CSSProp<MyTheme>
  *   }
  * }
  * ```
  */
  // ONLY string literals and inline invocations of css`` are supported, anything else crashes the plugin
  export type CSSProp<T = AnyIfEmpty<DefaultTheme>> =
    | string
    | CSSObject
    | FlattenInterpolation<ThemeProps<T>>;

  export default styled;
}

and sorry that I’m posting this still on TypeScript repository, where it seems that DefinitelyTyped repository would be a better fit for this issue πŸ˜…

123reactions
VladKabantsovcommented, May 13, 2020

Try to use

export const EditableAuthorTag = styled(AuthorTag as any)

Read more comments on GitHub >

github_iconTop Results From Across the Web

Disable waring 'Type of property circularly references itself in ...
So here the issue with js and vscode. If i say data type is /** @param {A} [data] */ the error are from...
Read more >
Disable Waring 'Type Of Property Circularly References Itself ...
In JavaScript it is a runtime error to use a nonobject type on the right side of the in operator. TypeScript 4.2 ensures...
Read more >
Type of property 'defaultProps' circularly references ... - Doriri
Props 전달에도 이상이 μ—†μ—ˆκ³  μ–΄λ–€ 였λ₯˜μΈκ°€ μ‹Άμ–΄μ„œ 검색해봀닀. Type of property 'defaultProps' circularly references itself in mapped type.
Read more >
Type of property 'defaultProps' circularly references itself in ...
Type of property 'defaultProps' circularly references itself in mapped type 'Pick<ForwardRefExoticComponent<Pick<Pick<any, Exclude&Β ...
Read more >
Type of property 'defaultProps' circularly ... - Code Grepper
Type of property 'defaultProps' circularly references itself in mapped type 'Pick<ForwardRefExoticComponent<Pick<Pick<any, Exclude<keyof.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found