打字稿 - 内联未定义检查不起作用(对象可能是“未定义”.ts(2532))

Ser*_*giu 2 javascript typescript tsc

我收到以下打字稿错误:

const myFunction = (
  param1: string | undefined,
  param2: { someProp: string } | undefined
) => {
  if (!param1 && !param2) {
    return;
  }

  // Here I get the following Typescript error:
  //  (parameter) param2: { someProp: string } | undefined
  //  Object is possibly 'undefined'.ts(2532)
  const param3 = param1 ? param1 : param2.someProp;
};
Run Code Online (Sandbox Code Playgroud)

以下作品:

const param4 = param1 ? param1 : param2 ? param2.someProp : null;
Run Code Online (Sandbox Code Playgroud)

但两次检查 null 或 undefined 似乎是多余的。

我不得不提到该strictNullChecks选项true在 compilerOptions 中设置为并希望保持这样。

知道为什么我会收到这个错误吗?

这是一个带有代码的 CodeSandbox:https ://codesandbox.io/s/jn2mp01q2v

jca*_*alz 6

关于 TypeScript 编译器的可悲事实是,它不像人类那么聪明(无论如何,就像 TypeScript 3.4 一样),因此它的控制流分析只是您可以自己执行的那种分析的苍白阴影。当然,它的分析非常一致,而我最近没有吃东西时往往会变得更糟。

如果您对联合类型的变量执行检查,该变量完全消除了该联合的一个或多个组成部分,编译器将很乐意为您缩小变量的类型:

param1.charAt(0); // error, possibly undefined
if (!param1) return;
param1.charAt(0); // okay now
Run Code Online (Sandbox Code Playgroud)

但是编译器没有做的一件事是跟踪可区分联合之外的相关变量。你通过检查消除了什么

if (!param1 && !param2) return;
Run Code Online (Sandbox Code Playgroud)

param1param2可以同时存在的可能性undefined。您已经采用了两个以前的独立变量,并使它们相互关联。编译器没有跟踪。由于param1param2仍然可以undefined(只是不是同时),编译器将它们视为仍然独立的,并且您会遇到问题。

您可以按照其他答案的建议进行操作并使用type assertion,这适用于您比编译器更聪明并且不想试图引导编译器完成理解您已经知道的任务的情况:

const param3 = param1 ? param1 : param2!.someProp; // I'm smarter than the compiler 
Run Code Online (Sandbox Code Playgroud)

请注意,我使用了非空断言运算符 !,这可能是断言您对机器的优越性的最简洁方式。还要注意这样的断言是不安全的,因为你可能会误解你的优越性。因此,只有做这样的事情后,你双重和三重检查,有没有办法param2undefined


您可以做的另一件事是重构您的代码,以便引导编译器完成它可以执行的分析。

const param3 = param1 || (param2 ? param2.someProp : undefined);
if (!param3) return;
param3.charAt(0); // string
Run Code Online (Sandbox Code Playgroud)

这对您有用,您只需检查每个参数一次。变量param3的类型为string | undefined,并且仅undefinedparam1param2都为假时才为。该代码中的每一步都完全消除了每个变量的联合成分,而不会留下任何相关类型来混淆编译器。

任何一种解决方案都应该适合您。希望有所帮助;祝你好运!