我目前正在处理leetcode中名为“Merge Two Binary Tree”的问题。
我用TypeScript解决了这个问题,我的解决方案通过了测试,但是编译器显示了这样的错误。
我不明白的是,我清楚地涵盖了每一种情况,TS应该猜测root2在它大喊“root2可能为空”的时候不可能为空。
我是否遗漏了任何情况,或者只是我不理解编译器的行为...?
如果你能给我指明正确的方向,我将不胜感激。
"我的解决方案"
const mergeTrees = (
root1: TreeNode | null,
root2: TreeNode | null
): TreeNode | null => {
if (!root1 && !root2) return null;
if (root1 && root2)
return new TreeNode(
root1.val + root2.val,
mergeTrees(root1.left, root2.left),
mergeTrees(root1.right, root2.right)
);
if (root1 && !root2)
return new TreeNode(
root1.val,
mergeTrees(root1.left, null),
mergeTrees(root1.right, null)
);
return new TreeNode(
root2.val,
mergeTrees(null, root2.left),
mergeTrees(null, root2.right)
);
}
3条答案
按热度按时间gpnt7bae1#
TypeScript的编译器所做的流分析是有限制的,虽然 * 你 *(和我们)从代码逻辑中知道
root2
在最后不可能是null
,但TypeScript不知道。您至少有三个选项:
1.在
root2
上使用非空类型Assert1.编写一个显式测试,如果
root2
为null
,则该测试将抛出Assert错误,并内联在该函数中1.使用类型Assert函数
使用非空类型Assert
值表达式末尾的
!
操作符是一个Assert,表示“我知道这个值永远不会是null
或undefined
('nullish ')”,所以你可以在所有三个地方使用它:或仅在一个位置中,通过分配给新标识符:
和所有类型Assert一样,如果你的逻辑出错,TypeScript将无法帮助你,因为它会相信你告诉它的东西。因此,如果逻辑出错,当
root2
为空时,你将得到一个意外的错误。root2
的显式内联测试您还可以添加运行时检查并抛出Assert错误:
这样做的好处是既测试了Assert,又提供了一个明确的错误,从而使TypeScript的编译器放心。
类型Assert函数
这和上面的方法差不多,但是是在一个可重用的包中,你可以编写一个可重用的类型Assert函数来测试空值并抛出错误:
这有同样的优点,它既测试了Assert,也保证了编译器。
s6fujrry2#
您可以使用nullish coalescing和三元组来缩短代码,这也应该允许编译器解析类型
pftdvrlh3#
我不熟悉 typescript ,但我可以在正确的方向上提供帮助:在C#中有一种情况,你可以有可空变量和不可空变量,通常在你使用这些可空变量之前,你必须让它们变成不可空变量。
如C#中的示例: