Typescript - 内联未定义检查不起作用(对象可能是 'undefined'.ts(2532))

Typescript - Inline undefined check not working (Object is possibly 'undefined'.ts(2532))

我收到以下打字稿错误:

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;
};

以下作品:

const param4 = param1 ? param1 : param2 ? param2.someProp : null;

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

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

知道为什么会出现此错误吗?

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

因为你给了param2两种类型,一种是object,另一种是undefined。 你必须给

常量参数 3 = 参数 1 ? param1 : (param2 as any).someProp;

那它一定能用。

关于 TypeScript 编译器的可悲事实是,它并不像人类一样聪明(无论如何从 TypeScript 3.4 开始),因此它 control flow analysis 只是那种分析的苍白影子你可以表现自己。当然,它的分析是非常一致的,而我最近没吃东西的时候往往会变得更糟。

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

param1.charAt(0); // error, possibly undefined
if (!param1) return;
param1.charAt(0); // okay now

但是编译器没有做的一件事就是跟踪 correlated variables outside of discriminated unions。您通过检查

消除的内容
if (!param1 && !param2) return;

param1param2同时为undefined的可能性。您采用了两个先前独立的变量,并使它们相互关联。编译器不跟踪的内容。由于 param1param2 仍然可以是 undefined(只是不同时),编译器将它们视为仍然独立并且你留下了你的问题。

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

const param3 = param1 ? param1 : param2!.someProp; // I'm smarter than the compiler 

请注意,我使用了 non-null assertion operator !,这可能是证明您优于机器的最简洁的方式。还要注意这样的断言是不安全的,因为您可能 错误 关于您的优势。所以只有在你仔细检查并三次检查 param2 不可能成为 undefined.

之后才做这样的事情

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

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

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

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