What you are looking for are mixins, this PR explains how to achieve deriving from a generic parameter. There are several changes that must be made to your code and to the code in the PR for your scenario:
- The
ImportedType interface which represents must be generic in order to flow information about the type created by the constructor
- The PR sample does not constrain the parameters to the constructor at all, and you want to ensure only constructors with a single name parameter are passed, if you just replace the general signature with yours, an errors occurs, I did however find a work around.
Implementation:
export interface ImportedType<T> {
new(name: string): T;
}
export interface Extended<T>{
foo: (value: any) => any;
bar(other: T): T; // If Extended also has T in the interface
}
function doSomething<T>(cls: ImportedType<T>) {
function mixin<U extends new(...args: any[]) => any>(Base: U) {
return class ExtendedClass extends Base implements Extended<ExtendedClass> {
constructor(...args: any[]) {
super(...args); }
foo (value: any) : any {
}
bar(other: ExtendedClass): ExtendedClass {
return this;
}
}
}
return mixin(cls)
}
//Usage:
class Foo {
static fooStatic: string;
constructor(public name: string) {
}
public getName(): string {
return this.name;
}
}
let FooExt = doSomething(Foo);
var foo = new FooExt("");
foo.getName(); // from original version
foo.foo(0) // from extended version
FooExt.fooStatic // Statics will not work unfortunately
Edit
If you want to add static methods to the class, you can do it like this:
export interface ImportedType{
new(name: string): any;
}
export interface Extended{
foo: (value: any) => any;
}
function staticMixin<T extends ImportedType>(cls: T) : T & Extended{
let extCls = <T & Extended> cls;
extCls.foo = (v: any) => {
console.log("Here");
}
return extCls;
}
// Usage
let FooExtStatic = staticMixin(Foo);
var foo2 = new FooExtStatic(""); //ok
FooExtStatic.foo(0); // static method
FooExtStatic.fooStatic // also works
Classis an instance of a class? Or you want it to be the actual class which you want to extend withfoo?