javascript - 打字稿 - 内联未定义检查不起作用(对象可能是'未定义'.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
解决方案
关于 TypeScript 编译器的可悲事实是,它不像人类那么聪明(无论如何从 TypeScript 3.4 开始),因此它的控制流分析只是你可以自己执行的那种分析的一个苍白阴影。当然,它的分析非常一致,而我最近没吃东西的时候会变得更糟。
如果您对联合类型的变量进行检查,该变量完全消除了该联合的一个或多个组成部分,编译器将很乐意为您缩小变量的类型:
param1.charAt(0); // error, possibly undefined
if (!param1) return;
param1.charAt(0); // okay now
但是编译器不做的一件事是跟踪有区别的 union之外的相关变量。你通过检查消除了什么
if (!param1 && !param2) return;
是两者param1
和param2
可以同时存在的可能性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
当两者param1
和param2
都是假的时才成立。该代码中的每一步都完全消除了每个变量的联合成分,而不会留下任何相关类型来混淆编译器。
任何一种解决方案都应该适合您。希望有帮助;祝你好运!
推荐阅读
- javascript - 自定义标记函数如何与 JavaScript 中的标记模板字符串一起使用?
- sqlite - Lisp cl-dbi - how to embed control characters in sqlite queries
- angular - My Angular 7 app is telling me 'The selector ... did not match any elements'
- javascript - Ajax request not working using differnt version of php
- r - Creating a time series plot and converting numeric data to date
- google-drive-api - Java 的 Drive API 客户端库是否在代号 1 中起作用
- linux - 当使用 memfd_create 系统调用时,内存分配在哪里?
- azure-devops - Azure 管道 Docker `所有管道实例都忙`
- node.js - 在 AppEngine 延迟问题上运行的 NodeJS REST API
- google-apps-script - 显示 - 使用切换按钮删除 X?