Skip to content
This repository has been archived by the owner on Jan 29, 2024. It is now read-only.

support for class-factory mixins #223

Open
trusktr opened this issue May 20, 2020 · 5 comments
Open

support for class-factory mixins #223

trusktr opened this issue May 20, 2020 · 5 comments
Labels
enhancement New feature or request

Comments

@trusktr
Copy link

trusktr commented May 20, 2020

The following plain JS doesn't work:

function Foo(Base) {
  return class Foo extends Base {
    foo() { console.log('foo') }
  }
}

class Bar {
  bar() { console.log('bar') }
}

class Baz extends Foo(Bar) {
  baz() { console.log('baz') }
}

const b = new Baz
b.foo()
b.bar()
b.baz()

try link

@JSMonk JSMonk added the enhancement New feature or request label May 20, 2020
@JSMonk
Copy link
Owner

JSMonk commented May 20, 2020

Thank you a lot ^_^.
We will add it soon.

@trusktr
Copy link
Author

trusktr commented May 20, 2020

I'm curious if it can be better than TS's. There are several problems with mixins in TypeScript:

Another example

@trusktr
Copy link
Author

trusktr commented Jun 6, 2020

The following is amazing, yet horrific: https://www.bryntum.com/blog/the-mixin-pattern-in-typescript-all-you-need-to-know-part-2/

It is amazing that that technique for making class-factory mixins in TypeScript can make them more class-like, but the syntax, non-DRY-ness (or WET-ness as in Write Everything Twice), and complicated mapped types are the horrific part.

If Hegel could achieve mixins but without all that complexity, and with support for declaration emit (or in other words full support for mixins as library exports, unlike in TypeScript), I would seriously consider dropping TypeScript for Hegel. Is it possible, without mapped types? I suppose it would be like hidden mapped types within the Hegel implementation, without mapped types required by the user?

@trusktr
Copy link
Author

trusktr commented Jun 6, 2020

As another example of the current complexity, here's my Mixin implementation (which itself isn't that long) and the unit tests (but the README has better more practical examples). But it gets complicated at the usage sites, for example.

It is riddled with issues. For example, in that last example, if I change the lines

const _Base = Constructor(Base)
const Parent = Observable.mixin(TreeNode.mixin(_Base))

to

const Parent = Observable.mixin(TreeNode.mixin(Constructor(Base)))

it completely breaks (for no intuitive reason). The Constructor(Base) constructor expression must be assigned to a new variable first, for it to work.

It's little things like that, plus all the other issues like having to follow the patterns with the mapped typed that you see in that example, that make it all too complicated compared to plain JS.

@web-padawan
Copy link

I'm also interested in class mixins, and the developer experience with TypeScript has been quite painful in this regard.

Here is one more issue which wasn't mentioned above: microsoft/TypeScript#17744. See my comment there for an overview of techniques that I tried, including the workaround for using protected methods.

Generally, this might be beneficial for web components libraries, such as Lion, Vaadin, Spectrum and others.
We have to use class mixins when creating custom elements classes that extend HTMLElement.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants