typescript - TypeScript:对象在联合类型上可能为空
问题描述
我有一个基本接口,其中至少需要两个属性之一。
interface Base {
someProp: { subProp: string; } | null;
condProp1?: boolean;
condProp2?: boolean;
}
interface WithProp1 extends Base {
condProp1: true;
}
interface WithProp2 extends Base {
condProp2: true;
}
export type MyType = WithProp1 | WithProp2;
MyType
当我在检查someProp
不为空并检查condProp1
或检查真实性之后尝试使用时condProp2
,编译器仍然认为someProp
可能是null
.
function doSomething(myType: MyType) {
if (myType.someProp && (
myType.condProp1 && myType.someProp.subProp === 'foo' ||
myType.condProp2 && myType.someProp.subProp === 'bar')) {
console.log("It's true, isn't it? It's really true.");
}
}
在doSomething()
,myType.someProp.subProp
给出一个编译时错误,说someProp
可能是null
. 如果我在函数签名中替换MyType
为,则不会发生这种情况。Base
// Compiles fine
function doSomethingBase(myType: Base) {
if (myType.someProp && (
myType.condProp1 && myType.someProp.subProp === 'foo' ||
myType.condProp2 && myType.someProp.subProp === 'bar')) {
console.log("It's true, isn't it? It's really true.");
}
}
将顺序切换myType.someProp.subProp === 'foo' && myType.condProp1
为第一行的解决方法,但不是第二行。知道为什么会发生这种情况或如何解决它(我可以使用 a!
但我不应该这样做)?似乎是编译器中的一个错误。
我正在使用 TSC 版本 3.5.3。 TypeScript 游乐场
解决方案
我怀疑这实际上是一个编译器错误;我不太了解内部结构,但我怀疑编译器将初始保护子句评估为 type Base
,然后将内部子句评估为WithPropX
, 并且正在丢失 myType asWithPropX
已经被防范 null someProp的信息.
您可以通过反转检查的顺序来解决此问题,因此更具体的类型推断发生在条件的早期(然后 someProp 空检查发生在编译器知道 myType 是 aWithPropX
而不是 a 的点Base
):
function doSomething(myType: MyType) {
if (myType.condProp1 && myType.someProp && myType.someProp.subProp === 'foo' ||
myType.condProp2 && myType.someProp && myType.someProp.subProp === 'bar') {
console.log("It's true, isn't it? It's really true.");
}
}
这个问题似乎与您在此处观察到的有关。
推荐阅读
- wordpress - 解析错误:语法错误,第 4311 行 /wp-includes/functions.php 中的文件意外结束
- javascript - 设置 cookie 后运行脚本而不重新加载页面
- html - Conditional pattern to be used along with required Angular7/8
- hadoop - 清理本地 tmp 后纱线未启动
- julia - 如何在不关闭 Julia 环境的情况下清理 Plots (GR)
- javascript - 我需要通过 url 下载 PDF
- yocto - bitbake 构建找不到稀疏的
- python - 按类别组合列表并为每个列表创建带有描述的新列
- angular - Angular 6 app 组件和子组件执行
- sql - 在 MS-ACCESS 的 1 个概览中显示来自不同查询的结果