我有以下玩具示例,其中打字稿警告我有错误:
type obj = {
ok: "ok" | "error",
}
function main(a: obj){
a.ok = "ok";
reloadFromDatabase(a);
if (a.ok == "error"){ // TS error
console.log("Error");
}
}
// Any function that has side effects on object a.
// For example, typeorm's `a.reload()`
function reloadFromDatabase(a: obj){
a.ok = "error";
}
错误是:
This comparison appears to be unintentional because the types '"ok"' and '"error"' have no overlap.(2367)
如果您假设不允许变异对象的副作用,这是有道理的,但
a
的类型是obj
,因此它应该允许"ok" | "error"
的两个值(obj.isOk
)。
在这个特定的代码示例中,我手上有一个有副作用的函数,这很好,因为我可以返回变异的对象:
function main(a: obj){
a.ok = "ok";
a = reloadFromDatabase(a);
if (a.ok == "error"){ // This time its fine
console.log("Error");
}
}
function reloadFromDatabase(a: obj){
a.ok = "error";
return a;
}
但在我的用例中,我无权访问
reloadFromDatabase
并且它什么也不返回(它只是改变对象)。
这是打字稿选项吗?这看起来像是一个合法的错误吗?我是否错过了允许突变会完全破坏打字稿逻辑(提供较少/没有类型安全)的情况?
这是控制流分析中所做权衡的一部分:
您可以看看这个著名的问题:https://github.com/microsoft/TypeScript/issues/9998
解决此问题的方法是使用类型断言:
if (a.ok as obj['ok'] == "error") { // ok asserted as 'ok'|'error'
console.log("Error");
}