TypeScript 中 Object is possibly 'undefined' 错误
当我们尝试访问可能未定义(例如标记为可选)的对象的属性时,会发生“Object is possibly 'undefined”错误。 要解决该错误,请在引用等于 null
时使用可选链接进行短路,例如 p1?.address?.country
。
下面是产生上述错误的代码示例
type Person = {
address?: { // 👈️ could be undefined
country?: string;
city?: string;
};
};
const p1: Person = {};
// ⛔️ Error: Object is possibly 'undefined'.ts(2532)
p1.address.country;
Person
类型的地址属性被标记为可选,因此它可能未定义。
这就是我们无法安全访问国家或城市属性的原因。
为了解决这个问题,我们可以使用可选的链接
?.
运算符。
type Person = {
address?: {
country?: string;
city?: string;
};
};
const p1: Person = {};
// ✅ No error
const result = p1?.address?.country;
问号点 ?.
语法在 TypeScript 中称为可选链接,类似于使用点表示法访问对象的嵌套属性,但如果引用为空(null 或 undefined),它不会导致错误,而是简称 -返回未定义。
这种方法通常用于从远程 API 获取数据或从文件中读取数据,其中某些属性可能没有值。
另一种方法是使用简单的 if
语句作为类型保护。
type Person = {
address?: {
country?: string;
city?: string;
};
};
const p1: Person = {};
if (p1.address != undefined) {
console.log(p1.address.country?.toUpperCase);
console.log(p1.address.city?.toUpperCase);
}
我们使用 if
语句来检查 p1.address
属性是否不等于 undefined 或 null。
一旦我们进入 if 块,TypeScript 就知道
p1.address
属性是对象类型,而不是undefined
的。
请注意
,我们使用了松散不等于!=
,它同时检查未定义和 null。 我们可以使用严格不等于!==
专门检查未定义。
松散比较涵盖 undefined 和 null,因为在松散比较中,undefined 等于 null。
console.log(undefined == null); // 👉️ true
console.log(undefined === null); // 👉️ false
如果我们确定该属性不可能具有空值,则可以使用非空断言运算符。
type Person = {
address?: {
country?: string;
city?: string;
};
};
const p1: Person = {
address: {
country: 'Chile',
city: 'Santiago',
},
};
console.log(p1.address!.country); // 👉️ "Chile"
console.log(p1.address!.city); // 👉️ "Santiago"
感叹号是 TypeScript 中的非空断言运算符。
它在不进行任何显式类型检查的情况下从类型中删除
null
和undefined
。
当我们使用这种方法时,我们基本上是在告诉 TypeScript 这个值永远不会为 null 或 undefined。
我们在 address 属性之后使用它,所以我们告诉 TypeScript
p1.address
永远不会有 null 或 undefined 的值。
如果我们在 if 语句中进行比较,请使用逻辑与 &&
运算符来确保属性的类型正确。
type Person = {
address?: {
country?: string;
city?: string;
num?: number;
};
};
const p1: Person = {};
if (
p1?.address &&
typeof p1.address.num === 'number' &&
p1.address.num > 10
) {
console.log('success');
}
逻辑 AND &&
运算符确保地址属性不是未定义的,num 存在于对象上并且是一个数字,然后再将它与数字 10 进行比较。
这是必需的,因为如果引用为空(null 或 undefined),可选的链接运算符 ?.
将返回 undefined 并且 TypeScript 不允许我们将 undefined 与数字进行比较。
例如,这会失败:
type Person = {
address?: {
country?: string;
city?: string;
num?: number;
};
};
const p1: Person = {};
// ⛔️ Error: Object is possibly 'undefined'.ts(2532)
if (p1?.address?.num > 10) {
console.log('success');
}
结果可能具有未定义的值,因为这是可选链接 ?.
运算符短路时的返回值。
num
属性的值可能为 undefined,因此我们不能直接将它与数字进行比较。
避免出现错误的另一种常见方法是使用逻辑与 &&
运算符。
type Person = {
address?: {
country?: string;
city?: string;
};
};
const p1: Person = {};
if (p1.address && p1.address.country) {
// 👇️ const result: string
const result = p1.address.country;
}
如果左边的值是假的(例如
undefined
),逻辑 AND&&
运算符将不会计算右边的值。
if 条件中的所有值都必须为真,if 块才能运行。
真值是所有非假值。
JavaScript 中的假值是:undefined 、null 、false 、0 、""(空字符串)、NaN(不是数字)。
这就是为什么 TypeScript 能够在 if 块中推断结果变量的类型为字符串。
在这种情况下,解决“Object is possibly 'undefined'”错误的更好方法是使用
typeof
运算符。
type Person = {
address?: {
country?: string;
city?: string;
};
};
const p1: Person = {};
if (p1.address && typeof p1.address.country === 'string') {
// 👇️ const result: string
const result = p1.address.country;
}
我们明确检查
country
属性的类型是否为字符串。 这比检查值是否为真要好,因为空字符串在 JavaScript(和 TypeScript)中是假值。
这是一个示例,说明为什么使用 typeof 更好。
type Person = {
address?: {
country?: string;
city?: string;
};
};
const p1: Person = { address: { country: '' } };
if (p1.address && p1.address.country) {
// ⛔️ This doesn't run
const result = p1.address.country;
console.log(result);
} else {
// 👇️ this block runs
console.log('✅ this runs');
}
这个 else 块在上面的示例中运行。
country
属性指向一个空字符串(虚假值),因此在我们的场景中仅检查该值是否为真可能还不够。
尽可能明确并使用 typeof 运算符总是更好。 它可以帮助我们避免一些难以发现的错误。
当我们尝试访问可能具有未定义值的对象的属性时,会发生“Object is possibly 'undefined'”错误。 要解决该错误,请使用可选的链接运算符或类型保护来确保在访问属性之前引用不是未定义的。
相关文章
在 AngularJs 中设置 Select From Typescript 的默认选项值
发布时间:2023/04/14 浏览次数:78 分类:Angular
-
本教程提供了在 AngularJs 中从 TypeScript 中设置 HTML 标记选择的默认选项的解释性解决方案。
在 Angular 中使用 TypeScript 的 getElementById 替换
发布时间:2023/04/14 浏览次数:153 分类:Angular
-
本教程指南提供了有关使用 TypeScript 在 Angular 中替换 document.getElementById 的简要说明。这也提供了在 Angular 中 getElementById 的最佳方法。
在 TypeScript 中使用 try..catch..finally 处理异常
发布时间:2023/03/19 浏览次数:181 分类:TypeScript
-
本文详细介绍了如何在 TypeScript 中使用 try..catch..finally 进行异常处理,并附有示例。
在 TypeScript 中使用 declare 关键字
发布时间:2023/03/19 浏览次数:97 分类:TypeScript
-
本教程指南通过特定的实现和编码示例深入了解了 TypeScript 中 declare 关键字的用途。
在 TypeScript 中 get 和 set
发布时间:2023/03/19 浏览次数:172 分类:TypeScript
-
本篇文章演示了类的 get 和 set 属性以及如何在 TypeScript 中实现它。
在 TypeScript 中格式化日期和时间
发布时间:2023/03/19 浏览次数:161 分类:TypeScript
-
本教程介绍内置对象 Date() 并讨论在 Typescript 中获取、设置和格式化日期和时间的各种方法。
在 TypeScript 中返回一个 Promise
发布时间:2023/03/19 浏览次数:182 分类:TypeScript
-
本教程讨论如何在 TypeScript 中返回正确的 Promise。这将提供 TypeScript 中 Returns Promise 的完整编码示例,并完整演示每个步骤。
在 TypeScript 中定义函数回调的类型
发布时间:2023/03/19 浏览次数:221 分类:TypeScript
-
本教程说明了在 TypeScript 中为函数回调定义类型的解决方案。为了程序员的方便和方便,实施了不同的编码实践指南。
在 TypeScript 中把 JSON 对象转换为一个类
发布时间:2023/03/19 浏览次数:110 分类:TypeScript
-
本教程演示了如何将 JSON 对象转换为 TypeScript 中的类。