首页 > 解决方案 > 打字稿 - 内联未定义检查不起作用(对象可能是'未定义'.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选项是true在compilerOptions中设置的,想保持这样。

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

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

标签: javascripttypescripttsc

解决方案


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

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

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

但是编译器不做的一件事是跟踪有区别的 union之外的相关变量。你通过检查消除了什么

if (!param1 && !param2) return;

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

您可以执行其他答案的建议并使用type assertion,这适用于您比编译器更聪明并且不想尝试引导编译器完成理解您已经知道的内容的任务:

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当两者param1param2都是假的时才成立。该代码中的每一步都完全消除了每个变量的联合成分,而不会留下任何相关类型来混淆编译器。

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


推荐阅读