TypeScript - 如何处理可能为未定义的值?
我正在尝试使用一个可选参数,如果在调用函数时未包含该参数,它会自动被赋值。
当我在函数的全局作用域中使用这个参数时,我没有收到任何来自 linter 的错误,问题出现在我尝试在 forEach 内使用它时(我只在那里尝试过)。
以下代码是发生情况的示例:
interface opts {
optionalParam?: number
}
const func = (options: opts): void => {
// I assign a value to the optional parameter
options.optionalParam ??= 100
const obj = {
test: 8
}
obj.test = options.optionalParam * obj.test // ✅ It works perfect
const objs = [{
test: 6
}]
objs.forEach((obj) => {
obj.test = options.optionalParam * obj.test // ❌ The object is possibly "undefined".ts(2532)
ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ
})
}
我不完全理解为什么在一个地方它被检测为未定义,而在另一个地方却没有。🤔
答案#1
TypeScript 无法区分
objs.forEach(callback) // code that works with options
和
doSomethingAsynchronous().then(callback) // code that works with options
在第二种情况下,为什么可能会出现问题应该很清楚——在异步代码运行之前,你可能会将一个未定义的值赋回给 optionalParam。(options.optionalParam=undefined;)——该属性的类型为 number | undefined。
第一个使用 forEach 的案例也有类似的问题,因为你正在处理一个回调。
一种方法是移除回调,并改用 for 循环。
for (const obj of objs) {
obj.test = options.optionalParam * obj.test
}
另一种方法是将 optionalParam 提取到一个明确定义的变量中。
const func = (options: opts): void => {
const optionalParam = options.optionalParam ?? 100;
// proceed to reference optionalParam in the future
// don't reference `options` again
或者,更简洁地说
const func = ({ optionalParam = 100 }: opts): void => {
