Skip to content

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

Description

@amcasey

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.

Activity

  1. chin2km commented on May 13, 2020

    @chin2km

    Any update here? 🤔

  2. loolooii commented on May 13, 2020

    @loolooii

    Having the same issue using Styled Components with React and TypeScript 3.9.2

  3. theLiudas commented on May 13, 2020

    @theLiudas

    I'm having this issue aswell. It turns out that something has fucked up with the latest (or one of the latest) release(-s).
    I managed to resolve this temporarily by simply downgrading TS version to 3.6.5

    npm i -D typescript@3.6.5
    

    Should solve the issue 😄

  4. VladKabantsov commented on May 13, 2020

    @VladKabantsov

    Try to use

    export const EditableAuthorTag = styled(AuthorTag as any)
    
    
  5. kimmikirino commented on May 13, 2020

    @kimmikirino

    Try to use

    export const EditableAuthorTag = styled(AuthorTag as any)
    

    Thank you, it worked for me.

  6. added
    Needs InvestigationThis issue needs a team member to investigate its status.
    and removed
    DocsThe issue relates to how you learn TypeScript
    on May 13, 2020
  7. lukaskl commented on May 13, 2020

    @lukaskl

    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 #36696).

    This breaking change was mitigated by updating @types/styled-components DefinitelyTyped/DefinitelyTyped#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 DefinitelyTyped/DefinitelyTyped#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 😅

  8. AdamAnSubtractM commented on May 22, 2020

    @AdamAnSubtractM

    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 #36696).

    This breaking change was mitigated by updating @types/styled-components DefinitelyTyped/DefinitelyTyped#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 DefinitelyTyped/DefinitelyTyped#42619 e.g.:

    example content of styled-components.d.ts
    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 😅

    Upgrading the types worked for me. Thank you! 🙏

  9. sopianguyen commented on Jun 2, 2020

    @sopianguyen

    Still happening for me.. :'( I'm similarly trying to extend a component like follows:

    Type of property 'defaultProps' circularly references itself in mapped type 'Pick<ForwardRefExoticComponent<Pick<Pick<any, Exclude<keyof ReactDefaultizedProps<StyledComponentInnerComponent<WithC>, ComponentPropsWithRef<StyledComponentInnerComponent<WithC>>>, any>> & Partial<...>, any> & { ...; } & WithChildrenIfReactComponentClass<...>>, "defaultProps" | ... 2 more ... | "$$typeof">'.  TS2615
    
        28 | `;
        29 | 
      > 30 | export const PrimaryButton = styled(Button)`
           |                              ^
        31 |   background-color: ${props => props.theme.primaryColor};
        32 |   border: none;
        33 |   color: ${props => props.theme.textColorOnPrimary};
    

    My relevant packages are
    "typescript": "^3.6.5",
    "styled-components": "^5.1.1",
    "@types/styled-components": "^5.1.0",
    "@typescript-eslint/eslint-plugin": "^3.1.0",
    "@typescript-eslint/parser": "^3.1.0",

  10. 34 remaining items

  11. nhhockeyplayer commented on Dec 21, 2021

    @nhhockeyplayer

    seems to be buried in the mongoose generics defs
    those signatures appear to be klomped on klomp over time

    its a matter if reworking your generics
    <T>
    and constraint
    <T extends {id: Types.ObjectId | string | number}>
    generics signatures
    and actual call signatures

    I could be wrong but thats where I am at modeling my own custom DIY repositories for back end entity mgt

  12. Tomas2D commented on Mar 14, 2022

    @Tomas2D

    Issue still persist in version 4.6.2 Ryan Cavanaugh (@RyanCavanaugh)

  13. added a commit that references this issue on Nov 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Needs InvestigationThis issue needs a team member to investigate its status.RescheduledThis issue was previously scheduled to an earlier milestone

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions