Skip to content

Allow type parameters in base class expressions #26542

Closed

Description

Search Terms

typescript type parameters in base class expressions

Suggestion

Type parameters in base class expressions.

Use Cases and Examples

Let's start with a simple mixin [playground] (borrowed from proposal #13743):

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

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

// Tagged is a mixin with a type parameter.
const Tagged = <T, B extends Constructor = B>(Base: B) =>
  class extends Base {
    getTag(): T {
      // Just imagine I have a function that returns objects,
      // and I want to case them to T.
      return {} as T
    }
  }

class TaggedPoint extends Tagged(Point) {}

Now if I want to specify the type argument for Tagged, that's easy enough 1 [playground]:

class TaggedPoint extends Tagged<number>(Point) {}

But if I want to pass a derived class's type parameter as that argument, I cannot [playground]:

class UsesTheTag<T> extends Tagged<T>(Point) {
//                                 ^
// error: Base class expressions cannot reference
// class type parameters.
  useTag() {
    const tag: T = this.getTag()
  }
}

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript / JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. new expression-level syntax)

Footnotes

  1. Note, this requires the default type argument = B shown above, but I have never seen it used in documentation, Stack Overflow, or blogs on the issue of TypeScript mixins. Is that because TypeScript is not actually deducing the type parameter from the function argument?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions