Печальная правда о компиляторе 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
ложны. Каждый шаг в этом коде полностью устраняет составляющие объединения для каждой переменной, не оставляя никаких коррелированных типов, которые могли бы запутать компилятор.
Любое решение должно работать для вас. Надеюсь, это поможет; удачи!
person
jcalz
schedule
03.05.2019
the following works ...
it doesn't work еслиstrictNullChecks
установлено наtrue
- person bugs   schedule 03.05.2019