To create a class with different overloads, you can't define it directly. Instead, define your regular class and rename it to FooImpl
. Then declare a constant representing the constructor with the different overloads and assign the FooImpl
to it:
interface B {
hello(): string;
}
class FooImpl {
constructor(withB?: boolean) {
if (withB) {
Object.assign(this, { hello() {}})
}
}
}
const Foo : {
new(withB: boolean): FooImpl & B;
new() : FooImpl;
}= FooImpl as any;
const foo1 = new Foo(); // FooImpl
const foo3 = new Foo(true); // FooImpl & B
If your interface only has methods, you may also consider using generics and specifying the this
parameter on the interface methods. This will restrict their visibility to specific parameters for the type:
interface B {
hello(): string;
}
class Foo<T=void> {
private withB: T;
constructor(withB: T);
constructor();
constructor(withB?: boolean) {
}
hello(this: Foo<boolean>): string {
return "";
}
}
const foo1 = new Foo();
foo1.hello() // Invalid
const foo3 = new Foo(true);
foo3.hello() // Valid