Грустная правда о компиляторе TypeScript состоит в том, что он просто не такой умный, как человек (во всяком случае, с TypeScript 3.4), и поэтому его анализ потока управления является лишь бледной тенью анализа вы можете выполнить самостоятельно. Конечно, он очень последовательн в своем анализе, в то время как мой имеет тенденцию ухудшаться, когда я недавно не ел.
Если вы выполняете проверку переменной типа объединения, которая полностью исключает одну или несколько составляющих этого объединения, компилятор с радостью сузит тип переменной для вас:
param1.charAt(0); // error, possibly undefined
if (!param1) return;
param1.charAt(0); // okay now
Но одна вещь, которую компилятор просто не делает, это отслеживает коррелированные переменные вне различимых объединений . Что вы устранили, проверив
if (!param1 && !param2) return;
- это вероятность того, что param1
и param2
могут быть undefined
одновременно. Вы взяли две ранее независимые переменные и сопоставили их друг с другом. Который компилятор не отслеживает. Поскольку param1
и param2
могут по-прежнему иметь значение undefined
(только не одновременно), компилятор обрабатывает их как все еще независимые, и у вас остается проблема.
Вы можете сделать то, что предложил другой ответ, и использовать утверждение типа , которое предназначено для случаев, когда вы умнее компилятора и не хотите пытаться провести компилятор через задачу понимания того, что вы уже знаете:
const param3 = param1 ? param1 : param2!.someProp; // I'm smarter than the compiler ?
Обратите внимание, что я использовал оператор ненулевого подтверждения !
, который, возможно, является наиболее кратким способом, чтобы утверждать ваше превосходство над машиной. Также помните, что такие утверждения небезопасны, так как вы можете быть ошибочными в отношении вашего превосходства. Так что делайте что-то подобное только после двойной и тройной проверки, что param2
не может быть undefined
.
Еще одна вещь, которую вы можете сделать, это реструктурировать ваш код, чтобы провести компилятор через анализ, который он может сделать.
const param3 = param1 || (param2 ? param2.someProp : undefined);
if (!param3) return;
param3.charAt(0); // string
Это будет работать для вас, и вы проверяете каждый параметр только один раз. Переменная param3
имеет тип string | undefined
и равна undefined
, только если param1
и param2
ложные. Каждый шаг в этом коде полностью устраняет составляющие объединения для каждой переменной, не оставляя коррелированных типов, которые могут запутать компилятор.
Любое решение должно работать на вас. Надеюсь, это поможет; удачи!