Skip to content

Instance member function becomes instance member property in mapped types #38496

Open
@bajtos

Description

@bajtos

TypeScript Version: 4.0.0-dev.20200512

Search Terms:

  • instance member function becomes instance member property
  • mixin property of exported class expression may not be private or protected

Code

export class Application {
  protected getState() {
    return 'starting';
  }

  component(componentCtor: typeof Object) {
    // mount the component
  }
}

// Ideally, I'd like to write `function repositoryMixin(superClass: typeof Application)`, but that
// triggers "property of exported class expression may not be private or protected"
export function repositoryMixin<T extends MixinTarget<Application>>(superClass: T) {
  return class extends superClass {
    component(componentCtor: typeof Object) {
      super.component(componentCtor);
      // register repositories contributed by the component
    }
  }
}

// helpers to work around TypeScript limitations related to mixins

export type Constructor<T extends object> = new (...args: any[]) => T;

export type MixinTarget<T extends object> = Constructor<
  {
    // Enumerate only public members to avoid the following compiler error:
    //   Property '(some-name)' of exported class expression
    //   may not be private or protected. ts(4094)
    [p in keyof T]: T[p];
  }
>;

Expected behavior:

The code compiles cleanly.

Actual behavior:

$  tsc mixin-bug.ts
mixin-bug.ts:13:5 - error TS2425: Class '{ component: (componentCtor: ObjectConstructor) => void; }' defines instance member property 'component', but extended class '(Anonymous class)' defines it as instance member function.

13     component(componentCtor: typeof Object) {
       ~~~~~~~~~

mixin-bug.ts:14:13 - error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword.

14       super.component(componentCtor);
               ~~~~~~~~~


Found 2 errors.

Playground Link:

https://www.typescriptlang.org/play/?ts=Nightly#code/MYGwhgzhAECCAO8QEthgC7IPYDtoG8AoaaYLAW3lwFMd0AKMymugYXSwCcAuadAT3jUsAM2gB5AEYArasHQBKAsRLQA9GujksAVzp8AFtVIUqOWuhUBfQjcIi987Hk7UqEZB078AssgAeyDgAPAAq0NT+6LQAJjB+gTihYJwA5tTowQhIqBjOAHz59BA6Qpys4FC8oUpEJK7oOpx4oJAwkdE4cdAlZRVtyqomzOZ0jKYs6OxcvAJCohIycoqDQz2l1JwAdExmFuMjFtOcCgDcKkMa0K6pyBDRnNduWB5eyNQwZHScyJI60TFoJJ+IZjLtJhdoDYSDY7FcjCAyjAONAAO5cADW0BSui60FCgmoAGVgD94OhoChyJ48rgYK5wAC+FgtAEghBCIRIlROBS5sZWHT0JwdPIuGEIlFYjAsEt5PloABeaDmVHQehbTUpVIQXhgHD8ADaAF0lIqFaFzlz-Dy+YToAkgsk0hkJR1pdBZbJ5UroIKcPcRWLOMEVHVVFcAKI4HTkTYYYy4EAg+A6SQoYBaajkSSbZEssAANywyEB6CM0BEWBAICwqKCqWG8GQIE2EU4nBmkKuJAACp2ygJoAByeg4MBxhTDz1iblcJmtKCS+CuKDObuaEjkMAgnBYCm56Ar5CFhOex4r-fLagxLboCD0AAsAAYAJyPhSQw3waBBaAY6h+AWUJjWqb9jXOGFCHyc4gADy+YToAkgsk0hkJR1pdBZbJ5UroIKcPcRWLOMEVHVVFcAKI4HTkTYYYy4EAg+A6SQoYBaajkSSbZEssAANywyEB6CM0BEWBAICwqKCqWG8GQIE2EU4nBmkKuJAACp2ygJoAByeg4MBxhTDz1iblcJmtKCS+CuKDObuaEjkMAgnBYCm56Ar5CFhOex4r-fLagxLboCD0AAsAAYAJyPhSQw3waBBaAY6h+AWUJjWqb9jXOGFCHyc4gA

Related Issues:

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs InvestigationThis issue needs a team member to investigate its status.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions