Объект может быть нулевым внутри обратного вызова - PullRequest
1 голос
/ 10 апреля 2020

У меня есть следующий код:

             let ctx = ref.current.getContext("2d");
             if(ctx){
                ctx.lineWidth=1; // here is ok!
                ctx.strokeStyle=props.barStroke??"darkgray";// here is ok!
                ctx.fillStyle=props.barFill??"blue"; // here is ok!
                props.data.map((v,i)=>{
                    ctx.fillRect(i*10,0,10,props.height); //here it complain about ctx is possibly null!!
                    ctx.strokeRect(1*10,0,10,props.height);
                })

             }

Я проверил ctx, и поэтому ctx.lineWidth работает без ошибок, но внутри обратного вызова он сигнализирует, что объект может быть нулевым. Если я использую ctx?.method, код все равно работает, так как же ctx, проверенный на нулевое значение вне обратного вызова, может стать нулевым внутри него? Здесь ссылка, показывающая проблему.

Ответы [ 3 ]

1 голос
/ 10 апреля 2020

Согласно это :

Это работает, как задумано. Средство проверки типа знает, что ctx не является нулевым во время создания функции обратного вызова, но оно не знает, что ctx не является нулевым, когда вызывается обратный вызов (потому что bar является изменяемым свойством, которое может быть изменено до или между вызовами функции обратного вызова).

Предлагаемый способ сделать это - скопировать ctx в const local и затем использовать его в обратном вызове.

0 голосов
/ 10 апреля 2020

См. Ответ Матье Риглера для описания почему это происходит. Другое решение состоит в том, чтобы использовать for l oop вместо обратного вызова, поскольку обратный вызов (который TS недостаточно умен, чтобы определить, происходит именно тогда, когда он объявлен в обратном вызове .map) - это то, что вызывает проблему :

let ctx = document.querySelector<HTMLCanvasElement>('foo')!.getContext("2d");
if (ctx) {
    const props = {
        data: ['x', 'y'],
        height: 10
    }
    for (const [i, v] of props.data.entries()) {
        ctx.fillRect(i * 10, 0, 10, props.height);
        ctx.strokeRect(1 * 10, 0, 10, props.height);
    }
}
0 голосов
/ 10 апреля 2020

Попробуйте:

      let ctx = ref.current.getContext("2d");
         if(ctx) {
            ctx.lineWidth=1; // here is ok!
            ctx.strokeStyle=props.barStroke??"darkgray";// here is ok!
            ctx.fillStyle=props.barFill??"blue"; // here is ok!
            props.data.map((v,i)=>{
                ctx.fillRect(i*10,0,10, v.height); //here it complain about ctx is possibly null!!
                ctx.strokeRect(1*10,0,10, v.height);
            })

         }

Похоже, props не предсказано, не ctx. Потому что ctx уже упоминается как локальная переменная.

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