我有一个类似的 ts 课程
class Vector3 {
//-----PUBLIC VARS
x: number;
y: number;
z: number;
//-----CONSTRUCTORS
constructor(x?: number, y?: number, z?: number) {
this.x = x == undefined ? 0 : x;
this.y = y == undefined ? 0 : y;
this.z = z == undefined ? 0 : z;
}
//-----METHODS
SetValues(x: number, y: number, z: number): void {
this.x = x;
this.y = y;
this.z = z;
}
}
我编写了一个单元测试代码作为
function TestVector3() {
var lhs = new Vector3(1, 2, 3);
lhs.SetValues(1, 2, 3);
if (lhs.x != 2 || lhs.y != 6 || lhs.z != 12) {
throw "a";
}
lhs.SetValues(-1, 2, 3);
if (lhs.x != -1 || lhs.y != -2 || lhs.z != -3) {
throw "b";
}
}
它在 'lhs.x != -1' TS2367 上出错。 删除行“抛出“a”;”会消除这个错误,如何修复它?
这个错误不应该发生,我认为这太愚蠢了......
在这种情况下控制流分析确实是错误的,因为它是乐观的并且假设
SetValues
不会改变类实例。除此之外,你的代码对我来说没有意义。它总是会抛出“a”并且代码的其余部分永远不会到达。
如果您的代码确实是测试代码,那么无论如何您都应该为每种情况提供专用的测试功能。
作为一个令人讨厌的解决方法,你可以使用
@ts-ignore
// @ts-ignore
if (lhs.x != -1 || lhs.y != -2 || lhs.z != -3) {
throw "b";
}
if (lhs.x != 2 || lhs.y != 6 || lhs.z != 12) {
throw "a"
}
静态代码分析有其局限性。通过上述检查,您可以将
lhs.x
、lhs.y
和 lhs.z
的类型分别从 number
缩小到 2
、6
和 12
。
即,一旦到达下一条语句,编译器就知道
x
、y
和 z
的值分别是 2
、6
和 12
。因为否则的话,就会抛出错误,并且不会达到此语句。但在做的过程中
lhs.SetValues(-1, 2, 3);
TS 编译器无法知道此方法调用实际上更改了
x
、y
和 z
的值,因此类型缩小仍然完好无损。现在下面的比较似乎毫无用处,因为编译器仍然“知道”x
、y
和z
分别是2
、6
和12
。
if (lhs.x != -1 || lhs.y != -2 || lhs.z != -3) {
throw "b";
}
另一个解决方法是检查
lhs
是否为真。这样你就摆脱了狭窄。
function TestVector3() {
var lhs = new Vector3(1, 2, 3);
lhs.SetValues(1, 2, 3);
if (lhs && (lhs.x != 2 || lhs.y != 6 || lhs.z != 12)) {
throw "a";
}
lhs.SetValues(-1, 2, 3);
if (lhs && (lhs.x != -1 || lhs.y != -2 || lhs.z != -3)) {
throw "b";
}
}