Typescript child class function overloading
For someone who wants to extend a type. Basing on zlumer's answer, and using Intersection types
interface ConsumerGroup {
on(message: 'message'): void
on(message: 'error'): void
}
interface ConsumerGroup2 {
on(message: 'messageDecoded'): void;
on(message: 'rawMessage'): void;
}
// Intersection types
type ConsumerGroupEx = ConsumerGroup2 & ConsumerGroup;
function newEvent(): ConsumerGroupEx {
return "just for test" as unknown as ConsumerGroupEx;
}
const evt = newEvent();
evt.on('messageDecoded'); // ok
evt.on('message'); // ok
evt.on('error'); // ok
evt.on('notExist'); // compilation error
TypeScript complains about methods not being interchangeable: what would happen if you do the following?
let a:A = new A(); // a is of type A
a.Init(1)
a = new B(); // a is still of type A, even if it contains B inside
a.Init(1) // second parameter is missing for B, but totally valid for A, will it explode?
If you don't need them to be interchangeable, modify B
's signature to comply with A
's:
class B extends A {
Init(param1: number, param2?: string) { // param 2 is optional
// some more code
}
}
However, you might find yourself in a situation where you need to create a class with totally different method signature:
class C extends A {
Init(param1: string) { // param 1 is now string instead of number
// some more code
}
}
In this case, add a list of method signatures that satisfy both current class and base class calls.
class C extends A {
Init(param1: number)
Init(param1: string)
Init(param1: number | string) { // param 1 is now of type number | string (you can also use <any>)
if (typeof param1 === "string") { // param 1 is now guaranteed to be string
// some more code
}
}
}
That way the A
class doesn't have to know about any of the derived classes. As a trade-off, you need to specify a list of signatures that satisfies both base class and sub class method calls.