В машинописи, как вернуть экземпляр подкласса в функции stati c в базовом классе? - PullRequest
0 голосов
/ 13 февраля 2020

Вот мой код:

class BaseElement {
    public static create<T extends typeof BaseElement>(this: T ): InstanceType<T> {
        this.createHelper();
        const r = new this();
        return r;
    }
    public static createHelper() {
        // implementation omitted.
    }
}

Я надеюсь, что функция stati c create вернет экземпляр текущего типа (то же самое с this).

Но это не работает:

Type 'BaseElement' is not assignable to type 'InstanceType<T>'.

Обратите внимание, что create зависит от другой функции c (например, createHelper), поэтому я не могу используйте эту подпись

create<T extends BaseElement>(this: new () => T): T

Как исправить аннотацию типа приведенного выше кода? Заранее спасибо.

------------- update ----------------

Похоже, это не так возможно сейчас (кроме обходного пути в принятом ответе). Существует проблема отслеживания здесь

1 Ответ

1 голос
/ 13 февраля 2020

Я бы не стал смешивать универсальные параметры типа 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);
    }
}

Хорошо, надеюсь, это поможет; удачи!

Детская площадка ссылка на код

...