Search code examples
abstract-classtypescriptmultiple-inheritance

Multiple inheritance workarounds


I'm trying to discover a pattern for combining multiple interfaces into one abstract class. Presently I can combine multiple interfaces via implements, but an interface cannot declare a constructor. When I must introduce a constructor I'm forced to use an abstract class. When I use a abstract class I must re-declare the entire composite interface! Surely I'm missing something?

interface ILayerInfo {
    a: string;
}

interface ILayerStatic {
    b(): string;
}

class Layer implements ILayerInfo, ILayerStatic {
    constructor(info: ILayerInfo);
    a: string;
    b(): string;
}

ANSWER: Use new:

interface Layer extends ILayerInfo, ILayerStatic {
    new(info: ILayerInfo);
}

// usage: new Layer({ a: "" });

Solution

  • Declaring a constructor on the same interface as the instance members doesn't really make much sense -- if you're going to pass in a type dynamically to use in a constructor, it's the static side of the class that would be restricted. What you would want to do is probably something like this:

    interface Colorable {
        colorize(c: string): void;
    }
    
    interface Countable {
        count: number;
    }
    
    interface ColorCountable extends Colorable, Countable {
    }
    
    interface ColorCountableCreator {
        new(info: {color: string; count: number}): ColorCountable;
    }
    
    class ColorCounted implements ColorCountable {
        count: number;
        colorize(s: string) { }
        constructor(info: {color: string; count: number}) {
            // ...
        }
    }
    
    function makeThings(c: ColorCountableCreator) {
        var results: ColorCountable[];
        for(var i = 0; i < 10; i++) {
            results.push(new c({color: 'blue', count: i}));
        }
        return results;
    }
    
    var items = makeThings(ColorCounted);
    console.log(items[0].count);
    

    See also How does typescript interfaces with construct signatures work?