Typescript Почему тип guard не работает должным образом для массива объектов типа null-able union(strictNullChecks включен)

type Field = {test: {more: number} | null}
let fields: Field[] = [{test: {more: 55}}]

Transpiler выдает ошибку независимо от типа охранника:

if (fields[0].test) {
  fields[0].test.more = 55 // object is possibly null
} 

Здесь нет ошибки:

function f(field: Field) {
  if (field.test) field.test.more = 15 // no error
}

2 ответа

Решение

Тип потока не отслеживает доступ к индексу массива, поэтому он не будет помнить, что вы проверили 0 индекс для null, Это было рассмотрено, но, по-видимому, не реализовано из-за соображений производительности. Вы можете поместить значение в локальную переменную, и средства защиты типов будут работать так, как ожидается:

type Field = {test: {more: number} | null}
let fields: Field[] = [{test: {more: 55}}]
let d = fields[0];
if (d.test) {
    d.test.more = 55 // object is possibly null
} 

Что ж, похоже, что TypeScript не отслеживает пустые значения в индексах Array, что немного странно... возможно, на GitHub может быть открыт вопрос об этом. Во всяком случае, есть способ предотвратить эту ошибку. Как только вы сделаете эту проверку, вы знаете, что test не является nullтак что вы можете сделать:

if (fields[0].test !== null) {
  fields[0].test!.more = 55 // object is possibly null
}

! после test скажет компилятору, что эта переменная определена и отличается от null или же undefined,

Другие вопросы по тегам