Skip to content

Exposing type and object from class factories. #13798

Closed
@shlomiassaf

Description

@shlomiassaf

Following the great mixin implementation by @ahejlsberg (#13743)

Having a mixin function returns a class is powerful but requires manual type declaration.

interface Tagged {
  _tag: string;
}

class Point {
  constructor(public x: number, public y: number) {}
}

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

function Tagged<T extends Constructor<{}>>(Base: T) {
  return class extends Base {
    _tag: string;
    constructor(...args: any[]) {
      super(...args);
      this._tag = "";
    }
  }
}

export const TaggedPoint: Constructor<Tagged> & typeof Point = Tagged(Point);
const tPoint: TaggedPoint; // ERROR: Cannot find name 'TaggedPoint'

We can't use TaggedPoint as a type, unless we:

export type TaggedPoint = Constructor<Tagged> & typeof Point;
const tPoint: TaggedPoint; // NOW OK

Using classes we can

export class Customer extends Tagged(Person) {
    accountBalance: number;
}

Which exposes the type but forces the developer to extend the Customer class.

My feature request is allowing:

export class TaggedPoint = Tagged(Point);

Which will be just sugar for:

export const TaggedPoint = Tagged(Point);
export type TaggedPoint = Constructor<Tagged> & typeof Point;

Maybe even:

export class TaggedPoint = Tagged(Point) { // user can extend here...
}

but that's not the main point...

The motivation for this is a more robust mixin mechanism that revolves around the base class and allow mixin's to know about it, using generic it provides powerful combinations.

So I can have

RestMixin(Base, Mixin1, Mixin2);

And the return type can have members from Mixin1 knowning about Base, using interfaces one can even set static members of a mixin to return T which is the instance of RestMixin(Base, Mixin1, Mixin2) all together.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Out of ScopeThis idea sits outside of the TypeScript language design constraintsSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions