question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support mixins for abstract classes

See original GitHub issue

Search Terms

Related to #32122, but not the same. abstract mixins classes

Suggestion

Right now we can’t to extending abstract classes with mixins. So, it would be nice to create a solution for this case.

Use Cases

abstract class Test {
}

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

function MyAwesomeMixin<T extends Constructor>(Constructor: Constructor) {
  abstract class MyAwesomeMixin extends Constructor {
  }
  return MyAwesomeMixin;
}

class A extends MyAwesomeMixin(Test) {
  /* Argument of type 'typeof Test' is not assignable to parameter of type 'Constructor'.
  Cannot assign an abstract constructor type to a non-abstract constructor type.(2345) */
}

Okay, try to create abstract constructor type:

type Constructor = abstract new (...args: any[]) => any;
/* Syntax error */

Hmm,…

Examples

Here is two way to create solution for this problem:

  1. (simple) Allow create abstract constructor types
type Constructor = (new (...args: any[]) => any) | (abstract new (...args: any[]) => any);
  1. (complex, but beautiful) Add new syntax to define mixins, and initially add support to extending abstract classes, like this:
abstract class Test {
   abstract mainMethod(): void;
}

mixin MyAwesomeMixin {
   public someMethod(): void {
      console.log('hello');
   }
}

class A extends MyAwesomeMixin(Test) {
   public mainMethod(): void {
      this.someMethod();
   }
}

// AND

abstract mixin MyAwesomeAbstractMixin {
    abstract someMethod(): void;
}

class B extends MyAwesomeAbstractMixin(Test) {
   public mainMethod(): void {
      this.someMethod();
   }
}

// Also this can add support to extending mixins without Mixin(Mixin2(Mixin3(Class)))

mixin MyAwesomeExtendedMixin extends MyAwesomeAbstractMixin {
   public someMethod(): void {
      ...
   }
}

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. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript’s Design Goals.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:11
  • Comments:13 (2 by maintainers)

github_iconTop GitHub Comments

5reactions
dragomirtitiancommented, Nov 26, 2019

@fatcerberus you can’t new but you can inherit and call it in the constructor of the derived class.

Currently if the base class signature returns an abstract class (ie. You are extending something of type new (...args :any) => AbstractClass) , it is assumed that this represents an abstract class and this forces you to implement the abstract methods, when in reality new (...args :any) => AbstractClass could also represent the constructor of any derived class.

abstract class Foo {
  abstract m(): void;
}

class Bar extends Foo {
  m() { }
}

let base: new () => Foo = Bar 

class MyClass extends base { // error, but not really 

}

Playground Link

4reactions
dragomirtitiancommented, Nov 26, 2019

Also realetd https://github.com/microsoft/TypeScript/issues/29653, IMO. I came to the same conclusion, that there is a need for a way to define a constructor that is explicitly abstract.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Inheritance, Abstract Classes and Class Mixin in JavaScript
Mixin and Abstract classes are the templates that hold a set of properties that can be used in child classes and the order...
Read more >
Playground Example - Abstract Class Constructors - TypeScript
The mixin pattern involves having classes dynamically wrapping each other to "mixing in" certain features to the end result.
Read more >
Interfaces, Mixins and Building Powerful Custom Data ...
Mixins can be regarded as a specific strain of abstract base classes where they can house both concrete and abstract methods but don't...
Read more >
Abstract classes vs. interfaces vs. mixins - Stack Overflow
A mixin (sometimes called a trait) allows multiple inheritance of abstract classes. Mixins don't have the scary association that multiple inheritance has (due ......
Read more >
Dart - Differences Between extends, implements and mixin
In Dart, you can use the abstract keyword only on classes because abstract ... While Dart doesn't support multiple inheritances it supports ......
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