Еще один «объект, возможно,« неопределен », но он действительно не может быть - PullRequest
1 голос
/ 21 апреля 2020

TS сообщает об ошибке classi c «Возможно, объект« неопределен »» с приведенным ниже кодом, однако невозможно, чтобы значение было неопределенным. Что вызывает эту ошибку, чтобы сообщить? Ссылка на документы, где описано это поведение, была бы великолепна!

const maybeTrue = Math.random() < 0.5;

let myStr;

if (maybeTrue) {
  myStr = 'abc';
}

if (maybeTrue) {
  console.log(myStr.toLowerCase()); // Error here, `myStr` possibly undefined
}

Ссылка для игровой площадки

Ответы [ 2 ]

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

Компилятор TypeScript выполняет статический c анализ кода. Этот анализ показывает, что оператор, который читает значение myStr, может быть достигнут через путь кода, который инициализирует myStr (когда условие первого if равно true), или путь кода, который пропускает инициализацию.

Компилятор не запускает код, он не оценивает условия, он не «замечает», что оба оператора if используют одно и то же условие.

Для анализа оба if похоже на if (<condition>) { <statements> }. Для него важно только то, что <statements> не выполняются на всех путях кода, поэтому после первого if оператор myStr может быть инициализирован или не инициализироваться.

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

Как видно из сценария детской площадки. Сообщаемая ошибка очевидна в том, что let объявляет переменную, но она не инициализируется, поэтому она undefined.

. Тогда тип строки выводится из вашего присваивания внутри условного предложения.

Я не верю, что компилятор машинописного текста может сделать вывод, что во втором условном выражении переменная инициализируется и является строкой. Я видел некоторые проблемы GitHub, связанные с этим, я не могу найти ни одной ссылки, к сожалению.

Но мы можем это как-то проверить, на предоставленной вами площадке:

  • Если мы инициализируем переменную пустой строкой, ошибка исчезнет.
const maybeTrue = Math.random() < 0.5

let myStr = ""
if (maybeTrue) {
  myStr = 'abc'
}

if (maybeTrue) {
  console.log(myStr.toLowerCase())
}
  • Если переместить предложение console.log в первое if, ошибка не сообщается.
const maybeTrue = Math.random() < 0.5

let myStr = ""
if (maybeTrue) {
  myStr = 'abc'
  console.log(myStr.toLowerCase())
}

Взгляните сюда: https://www.typescriptlang.org/docs/handbook/type-inference.html и здесь https://www.typescriptlang.org/docs/handbook/advanced-types.html для более подробной информации о том, как реализованы типы

...