typescript - 打字稿推断该字段是真实的(不能未定义),没有用户定义的类型保护
问题描述
type Item = {
left?: { photoSrc: string };
};
type ItemRequired = {
left: { photoSrc: string };
};
const item: Item = {} as any;
if (item.left) {
const itemRequired: ItemRequired = item; // fails. Typescript still says left may be undefined
// I'd like Typescript to know that field left is truthy
}
我知道用户定义的类型保护。例如
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
我的问题:
- 为什么 Typescript 无法推断
left
不能未定义? - 这是否意味着我需要为我需要检查的每个类型的变体创建一个类型保护函数?没有更简单的方法吗?例如,我希望在证明该
left
字段不能未定义的 if 检查范围内时,我希望 Typescript 知道这一点。
这似乎是一个很常见的情况,但我找不到答案,如果有请见谅。
解决方案
要回答您的问题:
我假设是因为 Typescript 在这里对这两种类型进行了比较:Item
and ItemRequired
,而不是您想要的,即{ left:{ photoSrc:string } }
.
Typescript 通常可以在没有类型保护的情况下找出你使用的联合类型的哪一部分,但它还不是很完美。至于哪些会起作用,哪些不会起作用,这是视情况而定的,有很多可能的情况。
很多时候人们都想在没有类型保护的情况下逃脱,这是可以理解的,因为它通常看起来像是额外的、不必要的代码。但它确实是为这种确切情况设计的:
const itemIsItemRequired = (item: Item): item is ItemRequired =>
item.left !== undefined;
if (itemIsItemRequired(item)) {
const itemRequired: ItemRequired = item; // this works
}
推荐阅读
- flutter - PlacePicker 谷歌位置
- react-native - 我们如何使用 react-native-gifted-chat 库实现群聊功能
- async-await - 未捕获的 SyntaxError:await 仅在异步函数和模块的顶层主体中有效
- java - Freemarker 不在邮件模板上显示图像
- selenium - 如何使用 Selenium 和 python 单击 devtools 控制台选项卡
- php - 多列的 ORDER BY 不能与 mysql 中的 Join 一起使用
- postgresql - 无法升级实例,因为一个或多个数据库包含声明为 WITH OIDS 的表,目标版本不支持该表
- python - nbdev_build_lib - 类型错误:__init__() 缺少 2 个必需的位置参数:“cfg_path”和“cfg_name”
- python - 在python的grep命令中输入一个字符串
- git - 如何解决与 git 命令行的冲突以保持目标(Visual Studio 2019)?