Я бы не стал смешивать универсальные параметры типа c и условные типы, если вы не готовы использовать утверждения типа внутри реализаций метода: компилятор на самом деле не может проверить, что значение присваивается отложенный условный тип (один из которых зависит от какого-то общего параметра типа c, который еще не указан). Если вы действительно хотите это сделать, вы можете:
class BaseElementAsssert {
public static create<T extends typeof BaseElementAsssert>(this: T): InstanceType<T> {
this.createHelper();
const r = new this();
return r as InstanceType<T>; // assert here
}
public static createHelper() {
// implementation omitted.
}
}
Это прекрасно, если вы готовы взять на себя ответственность за проверку типов, как вы и утверждаете. Например, вы можете изменить присвоение r
на const r = new BaseElementAsssert();
, и компилятор не будет жаловаться. Когда вы утверждаете что-то в компиляторе, проще всего ie. Так что будьте осторожны.
В этом случае я бы, вероятно, переписал код так, чтобы тип generi c был предполагаемым типом экземпляра. Если вам нужен доступ как к свойствам stati c конструктора BaseElement
, так и к , у которого компилятор определяет тип экземпляра, вы можете использовать тип пересечения :
class BaseElement {
public static create<T extends BaseElement>(this: typeof BaseElement & (new () => T)) {
this.createHelper();
const r = new this();
return r;
}
public static createHelper() {
console.log("called createHelper on " + this.name);
}
}
Хорошо, надеюсь, это поможет; удачи!
Детская площадка ссылка на код