TypeScript:类型缩小:断言不是未定义的,因此从类型中排除
TypeScript: type narrowing: assert not undefined and hence exclude from type
这两行都在 _e[k]
上抱怨错误 "Object possibly undefined":
obj[k] = typeof _e[k] === "undefined" ? "" : _e[k].toString();
obj[k] = _e[k] === undefined ? "" : _e[k].toString();
_e[k]
是多种类型的联合,因此手动类型转换不适用。如何消除错误?
更新:
因此,以更一般的方式,我的问题可以表述为:是否有一种方法可以通过检查应排除的特定类型来缩小变量的类型?
最小示例:
class test {
a!: string;
b?: number;
}
const t: test = { a: "hi", b: 2 };
for (const k of Object.keys(t) as Array<keyof test>) {
console.log(t[k] == undefined ? "LOL" : t[k].toString());
}
因此,适用于我的用例(但不适用于许多其他情况)的(相当老套的)解决方法是:
obj[k] = _e[k] === undefined ? "" : String(_e[k]);
仍然对适用于更一般情况的(更好的)建议感兴趣(参见问题更新)
长期以来 bug/issue TypeScript 不执行 control flow analysis to narrow the type of a property if the property key is a variable: microsoft/TypeScript#10530;它没有得到解决,因为修复造成了很大的性能损失。在您的情况下,这意味着 _e[k]
上的类型保护检查不会影响 _e[k]
.
的后续使用
我推荐的解决方法是将索引访问的 属性 分配给一个新变量并检查它:
const ek = _e[k]; // new variable
obj[k] = typeof ek === "undefined" ? "" : ek.toString(); // no error now
新变量 ek
应用了正常的控制流类型分析,并且您的类型保护起作用了。
不同用例的其他可能性:
如果您已经针对 undefined
和 null
进行了检查,但编译器无法计算出来,最简单的更改是使用 non-null assertion operator !
:
obj[k] = typeof _e[k] === "undefined" ? "" : _e[k]!.toString(); // non-null assertion
您可以将您的类型排除代码重构到它自己的独立表达式中,这样您就不必重新检查原始值。例如:
obj[k] = (_e[k] || "").toString(); // refactor
该特定代码仅适用于唯一的 falsy 值 _e[k]
可以有 undefined
和 ""
。如果 _e[k]
可以是 0
那么那将给出不同的结果。一般来说,你可以创建一个新函数来做任何你想做的事情:
function defined<T, U>(x: T | undefined, dflt: U): T | U {
return typeof x !== "undefined" ? x : dflt;
}
obj[k] = defined(_e[k], "").toString(); // refactor 2
好的,希望其中之一对您有所帮助;祝你好运!
这两行都在 _e[k]
上抱怨错误 "Object possibly undefined":
obj[k] = typeof _e[k] === "undefined" ? "" : _e[k].toString();
obj[k] = _e[k] === undefined ? "" : _e[k].toString();
_e[k]
是多种类型的联合,因此手动类型转换不适用。如何消除错误?
更新: 因此,以更一般的方式,我的问题可以表述为:是否有一种方法可以通过检查应排除的特定类型来缩小变量的类型?
最小示例:
class test {
a!: string;
b?: number;
}
const t: test = { a: "hi", b: 2 };
for (const k of Object.keys(t) as Array<keyof test>) {
console.log(t[k] == undefined ? "LOL" : t[k].toString());
}
因此,适用于我的用例(但不适用于许多其他情况)的(相当老套的)解决方法是:
obj[k] = _e[k] === undefined ? "" : String(_e[k]);
仍然对适用于更一般情况的(更好的)建议感兴趣(参见问题更新)
长期以来 bug/issue TypeScript 不执行 control flow analysis to narrow the type of a property if the property key is a variable: microsoft/TypeScript#10530;它没有得到解决,因为修复造成了很大的性能损失。在您的情况下,这意味着 _e[k]
上的类型保护检查不会影响 _e[k]
.
我推荐的解决方法是将索引访问的 属性 分配给一个新变量并检查它:
const ek = _e[k]; // new variable
obj[k] = typeof ek === "undefined" ? "" : ek.toString(); // no error now
新变量 ek
应用了正常的控制流类型分析,并且您的类型保护起作用了。
不同用例的其他可能性:
如果您已经针对
undefined
和null
进行了检查,但编译器无法计算出来,最简单的更改是使用 non-null assertion operator!
:obj[k] = typeof _e[k] === "undefined" ? "" : _e[k]!.toString(); // non-null assertion
您可以将您的类型排除代码重构到它自己的独立表达式中,这样您就不必重新检查原始值。例如:
obj[k] = (_e[k] || "").toString(); // refactor
该特定代码仅适用于唯一的 falsy 值
_e[k]
可以有undefined
和""
。如果_e[k]
可以是0
那么那将给出不同的结果。一般来说,你可以创建一个新函数来做任何你想做的事情:function defined<T, U>(x: T | undefined, dflt: U): T | U { return typeof x !== "undefined" ? x : dflt; } obj[k] = defined(_e[k], "").toString(); // refactor 2
好的,希望其中之一对您有所帮助;祝你好运!