解决 TypeScript 错误 Object is possibly 'null'
当我们尝试访问可能具有 null 值的对象的属性时,会出现错误“Object is possibly 'null'”。 要解决该错误,如果引用等于 null,需要使用可选的链接运算符 (?.)
进行短路,例如 emp?.address?.country
。
下面是产生上面错误的示例代码
type Employee = {
address: {
country: string;
city: string;
} | null; // 👈️ 可能是 null
};
const emp: Employee = {
address: null,
};
// ⛔️ Error: Object is possibly 'null'.ts(2531)
console.log(emp.address.country);
Employee 类型的地址属性可能为 null,这会导致错误。
为了解决这个问题,我们可以使用可选的链接 (?.)
运算符。
type Employee = {
address: {
country: string;
city: string;
} | null;
};
const emp: Employee = {
address: null,
};
// ✅ No errors
console.log(emp?.address?.country);
(?.)
语法在 TypeScript 中称为可选链接,就像使用点表示法访问对象的嵌套属性一样,但如果引用为空(null 或 undefined),它不会导致错误,而是短路返回未定义。
当从远程 API 获取数据或从文件中读取数据时,通常使用这种方法,其中某些属性可能没有值。
另一种方法是使用简单的 if 语句作为类型保护。
type Employee = {
address: {
country: string;
city: string;
} | null;
};
const emp: Employee = {
address: null,
};
// 👇️ 检查是否不为 null 或者 undefined
if (emp.address != null) {
console.log(emp.address.country);
console.log(emp.address.city);
}
我们使用 if 语句来检查 emp.address
属性是否不等于 null 或 undefined。
一旦我们进入 if 块,TypeScript 就知道 country 和 city 属性是字符串类型的。
请注意,我们使用了松散不等于 (!=)
,它检查 null 和 undefined。 我们可以使用严格不等于 (!==)
专门检查 null。
松散比较涵盖 null 和 undefined,因为在松散比较中 null 等于 undefined。
console.log(null == undefined); // 👉️ true
console.log(null === undefined); // 👉️ false
如果我们确定该属性不能具有 null 值,则可以使用非 null 断言运算符。
type Employee = {
address: {
country: string;
city: string;
} | null;
};
const emp: Employee = {
address: {
country: 'China',
city: 'BeiJing',
},
};
console.log(emp.address!.country); // 👉️ "China"
感叹号是 TypeScript 中的非空断言运算符。
它从类型中删除 null 和 undefined 而不进行任何显式类型检查。
当你使用这种方法时,你基本上告诉 TypeScript 这个值永远不会是 null 或 undefined。
我们在 address 属性之后使用它,所以我们告诉 TypeScript emp.address 永远不会有 null 或 undefined 的值。
如果在 if 语句中进行比较,请使用逻辑 AND (&&) 运算符来确保属性的类型正确。
type Employee = {
address: {
country: string;
city: string;
num?: number;
} | null;
};
const emp: Employee = {
address: null,
};
if (
emp.address &&
typeof emp.address.num === 'number' &&
emp.address.num > 50
) {
console.log('success');
}
逻辑与 (&&) 运算符确保属性 address
不为 null,该 num 存在于 address
对象上,并且在将其与数字 50 进行比较之前是一个数字。
这是必需的,因为如果引用为 null(null 或 undefined),可选的链接运算符 (?.)
将返回 undefined 并且 TypeScript 不允许我们将 undefined 与数字进行比较。
例如,下面的代码将产生错误:
type Employee = {
address: {
country: string;
city: string;
num?: number;
} | null;
};
const emp: Employee = {
address: null,
};
// ⛔️ 可以是 undefined, 所以比较是不被允许的
if (emp?.address?.num > 50) {
console.log('success');
}
结果可能具有 undefined 的值,因为这是可选链接 (?.)
运算符在短路时的返回值,TypeScript 不允许我们将可能 undefined 的值与数字进行比较。
避免出现错误的另一种常见方法是在访问属性时使用逻辑 AND (&&) 运算符。
type Employee = {
address: {
country: string;
city: string;
} | null;
};
const emp: Employee = {
address: null,
};
if (emp.address && emp.address.country) {
// 👉️ emp.address.country 这里是字符串类型
console.log(emp.address.country.toUpperCase());
}
如果左边的值是 false 的(例如 null),则逻辑 AND (&&) 运算符不会计算右边的值。
if 条件中的所有值都必须为真,if 块才能运行。
JavaScript 中的虚假值是:undefined、null、false、0、""(空字符串)、NaN(不是数字)。
这就是为什么 TypeScript 能够将 emp.address.country
属性的类型推断为 if 块中的字符串。
在这种情况下,解决“Object is possibly null”错误的更好方法是使用 typeof 运算符。
type Employee = {
address: {
country: string;
city: string;
} | null;
};
const emp: Employee = {
address: null,
};
if (emp.address && typeof emp.address.country === 'string') {
// 👉️ emp.address.country 在这里是字符串类型
console.log(emp.address.country.toUpperCase());
}
我们明确检查 country 属性的类型是否为字符串。 这比检查值是否为真要好,因为空字符串在 JavaScript(和 TypeScript)中是假值。
这是一个示例,说明了为什么使用 typeof 更好。
type Employee = {
address: {
country: string;
city: string;
} | null;
};
const emp: Employee = {
address: {
country: '',
city: '',
},
};
if (emp.address && emp.address.country) {
const result = emp.address.country;
console.log(result);
} else {
// 👉️ else block runs
console.log('✅ This block runs');
}
else 块在上面的示例中运行。
country
属性指向一个空字符串(假值),因此在我们的场景中仅检查该值是否为真可能还不够。
尽可能明确并使用 typeof 运算符总是更好,因为它可以帮助我们避免一些难以发现的错误。
当我们尝试访问可能具有 null 值的对象上的属性时,会发生“Object is possibly null”错误。 要解决该错误,需要在访问属性之前使用可选的链接运算符或类型保护来确保引用不为空。
相关文章
在 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 中的类。
使用 NPM 将 TypeScript 更新到最新版本
发布时间:2023/03/19 浏览次数:130 分类:TypeScript
-
本教程说明了如何使用 npm 更新到最新版本的 TypeScript。这将为如何使用 npm 将 TypeScript 更新到最新版本提供完整的实际示例。
使用 jQuery 和 TypeScript
发布时间:2023/03/19 浏览次数:151 分类:TypeScript
-
本教程提供了使用 jQuery 和 TypeScript 的基本理解和概念。