Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

is a constrained mixin pattern possible? #494

Open
krnsk0 opened this issue Jan 2, 2023 · 2 comments
Open

is a constrained mixin pattern possible? #494

krnsk0 opened this issue Jan 2, 2023 · 2 comments

Comments

@krnsk0
Copy link

krnsk0 commented Jan 2, 2023

I've got a project using mobx-keystone with a complex inheritance hierarchy, and I'm realizing I could simplify things if I switched to an inheritance pattern involving mixins.

The Typescript docs recommend an approach they call "constrained mixins", in which factory functions accept a base class constrained to a type which they extend and return. I'd like to figure out how to do something like this with ExtendedModel.

Here's where I'm at:

// A base class
class Entity extends Model({}) {}	

// An example factory that mixes in some functionality
function makeCountable<T extends ModelClass<Entity>>(Base: T) {
  class _Countable extends ExtendedModel(modelClass(Base), {
    quantity: tProp(types.number, 0)
  }) {

    @modelAction
    increment() {
      this.quantity += 1
    }
  }
  return _Countable
}

// An attempt at describing the Countable type so I can use it
// as a constraint below 
type Countable = ReturnType<typeof makeCountable>
                            
// A second factory which I'd like to be constrained to only accept classes which
// have passed through `makeCountable` already
function makeProducer<T extends ModelClass<Countable>>(Base: T) {
//                                         ^^^^^^^^^
//                                         Type 'typeof _Countable' does not
//                                         satisfy the constraint 'AnyModel
//                                         | AnyDataModel
  class _Producer extends ExtendedModel(modelClass(Base), {
    // etc.
  }) {
    // etc.
 
  }
  return _Producer
}
                            

Is there a way to make this work? I suspect there's something I should be doing differently specifying the constraint on the type argument to the factories (T Extends ModelClass<etc>). Or it could be that I need some other way of describing the return type of the factories to use as constraints (e.g. type Countable = ReturnType<typeof makeCountable>).

Once I figure out a pattern that works, I'd be happy to contribute it back to the docs on inheritance if this would be useful, generally.

@gbcreation
Copy link
Contributor

I'm also interested by the mixins approach.
Did you make any progress on this topic?

@krnsk0
Copy link
Author

krnsk0 commented May 5, 2023

I'm also interested by the mixins approach. Did you make any progress on this topic?

I was never able to sort this out, sadly! Using an inheritance hierarchy instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants