Разве не должен транспилятор машинописного текста предупреждать о вызове виртуальных методов из конструктора суперкласса? - PullRequest
0 голосов
/ 09 апреля 2019

Важной причиной для выбора Typescript в качестве нашего языка проектирования было предотвращение ошибок времени выполнения, таких как «X не определен». Однако мы все еще сталкиваемся с некоторыми из них при вызове виртуального метода из конструктора суперкласса.

Разве компилятор не должен выдавать ошибку за это?

В документации Typescript не упоминается, что вызовы виртуальных методов недопустимы (точнее: может не использоваться this).

Только один из участников предлагает написать правило проверки для проверки этого, другой пометил его как Ограничение проектирования

abstract class Base {
    constructor(protected readonly numbers: number[]) {
        this.initialise()
    }

    protected abstract initialise(): void 
}

class Extended extends Base {
    private readonly squares: number[] = []

    protected initialise() {
        this.numbers.forEach( num => this.squares.push( num * num ) )
    }
}

const extended = new Extended( [1,2,3,4,5] )

Приведенный выше код вызывает ошибку во время выполнения (проверьте ее на Playground . Вы увидите, что он будет проходить красиво, без ошибок или даже предупреждений. Но когда вы запустите его, консоль покажет ошибку )

Uncaught TypeError: Cannot read property 'push' of undefined
    at <anonymous>:30:68
    at Array.forEach (<anonymous>)
    at Extended.initialise (<anonymous>:30:22)
    at Extended.Base (<anonymous>:17:14)
    at new Extended (<anonymous>:24:47)

Свойство squares для Extended все еще не определено, когда конструктор Base вызывает метод initialise. Это связано с тем, как код преобразуется в Javascript. Хотя я могу понять основную причину, это очень раздражает компилятор не жалуется на это. Я видел предложения сделать «ленивую» инициализацию членов вроде Extended.squares, но мне очень нравится сохранять членов readonly в максимально возможной степени.

На самом деле, я действительно ожидал бы, что приведенный ниже код будет функционировать правильно (имея массивы numbers и squares, заполненные пятью числами). Но до тех пор, пока не разрешено использовать this до завершения всех суперконструкторов, компилятор должен указывать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...