This project is read-only.

Error with static methods in derived classes with same name but different parameter count

Topics: General
Jun 30, 2013 at 4:34 PM
Edited Jul 2, 2013 at 10:43 AM
I have classes which each have a static init() method but the parameters to the init in each class are different. It currently gives a compile error, is there any way around this? I'm creating a definitions file for an existing library so I can't change the API without a lot of hassle:
class A {
    static init() {}

class B extends A {
    static init(i:number) {}

// Existing library usage
Here is the compile error:
Class 'B' cannot extend class 'A':
Types of static property 'init' of class 'B' and class 'A' are incompatible:
Call signatures of types '(i: number) => void' and '() => void' are incompatible:
Call signature expects 0 or fewer parameters.
UPDATE: Here is a link to the code in the TypeScript Playground so you can just press the link to see the error:
Jul 2, 2013 at 8:16 PM
There's no simple workaround here, your API is violating some fundamental OO tenets. There's nothing special about static vs instance here, the rules are the same for each as far as overloading and assignability are concerned. If the parameter is optional you can mark it as such throughout the class hierarchy (potentially with a default value). If the parameter is not required for the base class then requiring it on a derived class doesn't make much sense. Consider:
var x: A = B;
what do you expect to happen here? A claims its init takes 0 arguments, but when dispatched at runtime we will be calling B's init which expects > 0 arguments of a particular type. You're asking anyone subclassing A to ensure they correctly handle their methods' arguments being optional even though the signature claims they are required. Similar things happen if you try to use these functions as values for assignment.
Jul 3, 2013 at 11:03 AM
Hi Dan, Thanks for replying. I was hoping static methods would be handled in a way similar to C#/C++ like this (the C# version):
class A {
    public static void init() {}

class B : A {
    public static void init(double i) {}

class Program {
    static void Main(string[] args) {
In the JavaScript library I'm trying to create definitions for (Cocos2D-HTML5) actually has a static create() on certain classes (e.g. cc.TransitionScene which extends cc.Scene) to create an instance of that type and in each derived class the parameters being passed to create() are different. I think this is a common pattern to have a static class method that acts like a constructor and to have different overloads for different derived classes.

My workaround for now is to remove typing with a init( any[]) parameter list so I can progress with the rest of the definitions file. It's not ideal but it'll do for now. I'll see if I can match up common parameters from all create methods later with the hope that they line up and I can make them optional as you suggested. Thanks again for the reply.
Jul 3, 2013 at 7:20 PM
Yeah I believe C# accomplishes this via static constructors to ensure object initialization happens in a way which helps with patterns like this and using static factory pattern type things. Your use of rest parameters seems a reasonable workaround for now, glad you were able to get unblocked. Feel free to open a Codeplex issue for this feature so that others can up vote it with their support.
Dec 19, 2013 at 8:12 AM
I found that described problem relevant for me too. I've created discussion with my reasons.