Независимо от того, что вы делаете с сигнатурами перегрузки, TypeScript решил, что статические методы будут наследоваться от родительских классов (, как это возможно в ES2015 ), поэтому вы не можете просто расширить класс и обойтиэтот.По крайней мере, до тех пор, пока TS не изменится.Например:
namespace Original {
declare namespace Classes {
class Parent {
static method(arg1: string): Parent;
parentProp: string;
}
class Child extends Parent {
static method(arg1: number, arg2: number): Child;
static method<T, V>(arg1: T): V;
childProp: string;
}
}
const child = new Classes.Child();
const parent = new Classes.Parent();
const alsoParent: typeof parent = new Classes.Child();
const childConstructorMethod = Classes.Child.method;
const parentConstructorMethod = Classes.Parent.method;
// the following inheritance should hold
const alsoParentConstructorMethod: typeof parentConstructorMethod = childConstructorMethod;
// which leads to this even without generics
alsoParentConstructorMethod("oopsie-daisy");
}
Это похоже на ваши классы, и вы можете видеть, что приведенное выше в конечном итоге позволит людям вызывать метод parent-signature для дочернего конструктора независимо от того, что вы делаете ... потому чтоможно назначить дочерний статический метод переменной типа родительского статического метода.Это наследование, и оно накладывает ограничения на вещи, которые вы не можете обойти с помощью подписей.
Так что вы можете сделать?Я бы подумал об изменении объявленных типов, чтобы вообще не использовать class
.Обратите внимание, что это не означает, что JS не может использовать class
;это просто означает, что лучший способ представить такого рода отношения с вашими типами и ценностями.Например:
namespace PossibleFix {
declare namespace Classes {
interface Parent {
parentProp: string;
}
export const Parent: {
method(arg1: string): Parent;
new (): Parent;
};
interface Child extends Parent {
childProp: string;
}
export const Child: {
method(arg1: number, arg2: number): Child;
new (): Child;
};
}
const child = new Classes.Child();
const parent = new Classes.Parent();
const alsoParent: typeof parent = new Classes.Child();
const childConstructorMethod = Classes.Child.method;
const parentConstructorMethod = Classes.Parent.method;
// now there is no implied inheritance on the static side
const alsoParentConstructorMethod: typeof parentConstructorMethod = childConstructorMethod;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ <-- error! not assignable
}
Это почти идентично оригинальному типу class
.class
имеет сторону экземпляра и статическую сторону.Здесь сторона экземпляра становится interface
, а статическая сторона становится экспортированной переменной const
, которая одновременно является конструктором (new():...
) и имеет метод.Но здесь, даже если сторона экземпляра наследует (у нас все еще есть Child extends Parent
), статические стороны теперь не связаны друг с другом.И это позволяет вам выбирать любые сигнатуры, которые вы хотите в методах дочернего конструктора.
В конечном итоге это будет более многословно, особенно если у вас есть реальный код TypeScript, который генерировал исходные объявления, поскольку теперь вам нужно придумать способ утверждать, что генерирующий код соответствует последним объявлениям,и это может быть грязно.Но это дает вам больше свободы.Надеюсь, это немного поможет.Удачи!
Ссылка на код