Это потому, что TypeScript не имеет polymorphi c this
типов для методов stati c. Существует давняя открытая проблема, microsoft / TypeScript # 5863 , с просьбой предоставить такую функцию. Пока это не часть языка, но, к счастью, комментарии по этому вопросу описывают обходной путь, который должен помочь вам найти то поведение, которое вам нужно:
class Base {
static create<T extends Base>(this: new () => T) {
return new this()
}
}
Здесь мы делаем create()
a generi c метод с параметром типа T extends Base
, который может быть вызван только для объекта, чей контекст this
является конструктором с нулевым аргументом и возвращает значение типа T
.
Поэтому компилятор знает, что Sub.create()
вернет Sub
, а Base.create()
вернет Base
:
Sub.create().fn() // okay
Base.create().fn() // Property 'fn' does not exist on type 'Base'
Это также имеет преимущество перед существующим кодом в том, что следующее теперь является ошибкой:
class Oops extends Base {
x: string;
constructor(x: string) {
super();
this.x = x.toUpperCase();
}
}
Oops.create(); // error!
Класс Oops
не имеет конструктора с нулевым аргументом, и поэтому реализация Oops.create()
в итоге вызовет new Oops()
без требуемого параметр и вызвать ошибку времени выполнения при попытке вызвать toUpperCase()
на undefined
.
Хорошо, надеюсь, это поможет; удачи!
Детская площадка ссылка на код