# Extending multiple classes in TypeScript

If you tried to extend multiple classes, you know you can't do something like 

    export class ChildClass extends ParentClass, GrandParentClass {}

without getting an error that you can extend only one class

But, you can do something like this

    const ExtendedParent = class ParentClass extends GrandParentClass {}
    export class ChildClass extends ExtendedParent {}

Now, let's do a mixin that will automagically do the extensions for you, no matter how many classes you need to extend.

    class ClassExtenderMixin {
      private superclass: any;

      constructor(superclass: any) {
        this.superclass = superclass;
      }

      with(...otherClassesMixins: any[]) {
        return otherClassesMixins.reduce((extendedClass, classMixin) => classMixin(extendedClass), this.superclass);
      }
    }

    export default (superclass: any) => new ClassExtenderMixin(superclass);

You call this mixin where you want to extend a class, like so:

    import extendClass from 'class.extender.mixin';

    export default class ChildClass extends extendClass(ParentClass).with(GrandParentClassMixin, GrandGrandParentClassMixin, etc)

And you need to define the other classes mixin as so:

    export default (superclass: any) => class extends superclass { // the content of GrandParentClass } 

What happens with the ClassExtenderMixin is:

1. when you call `extendClass(ParentClass)`, you make the ParentClass as the superClass of the new returned class; so you have something like:
    

    const ParentClassToExtend = extendClass(ParentClass)
    // this translates to
    const ParentClassToExtend = new ClassExtenderMixin(ParentClass)

    export default ChildClass extends ParentClassToExtend {}


2. next, you call the ParentClassToExtend `with` method, which takes the other classes mixins functions with the current class you are passing as arguments; 
Note that in the with's arguments, you transform the arguments in an array, with the  [rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters) and that's why you can call reduce on the method arguments. 


    // at first iteration, you call the mixin function and assign the extendedClass as
    // class extends ParentClass; let's call this ExtendedParentClass
    // this happens, because GrandParentClassMixin is defined as (superclass) => class extends superclass {}
    
    // at second iteration, you call the mixin function assign the extendedClass as
    // the class extends ExtendedParentClass
    // this happens because GrandGrandParentClassMixin is also defined as (superClass) => class extends superclass {}

    // and so on, if you have multiple extender mixins



You can use this method for extending an `AbstractClass` with `SomeSpecificMethodsClass` and `SomeOtherSpecificMethodsClass`


Note, I took this pattern from JavaScript. There is also another pattern for extending classes in TypeScript. 

    

