TypeScript 中的对象类型为“未知”错误

TypeScript 中的对象类型为“未知”错误

Object is of type ‘unknown’ Error in TypeScript

当我们尝试访问类型为 的值的属性时,会发生“对象类型未知”错误unknown要解决该错误,请在访问属性之前使用类型保护来缩小对象的类型,例如
if (err instanceof Error) {}.

对象的类型未知

以下是错误发生方式的示例:

索引.ts
async function fetchData() { try { await Promise.resolve(42); } catch (err) { // 👈️ err is type unknown // ⛔️ Error: object is of type unknown console.log(err.message); } }

我们无法保证catch块中的错误会提前成为一个Error
实例,因此 TypeScript 将其类型设置为
unknown以避免任何意外的运行时错误。

为了解决这个问题,我们必须在访问特定属性之前使用
类型保护来缩小对象的类型。

索引.ts
async function fetchData() { try { await Promise.resolve(42); } catch (err) { if (err instanceof Error) { // ✅ TypeScript knows err is Error console.log(err.message); } else { console.log('Unexpected error', err); } } }

我们使用
instanceof
运算符来检查是否
errError对象的实例。

如果是,我们可以安全地访问该message属性,因为所有Error
实例都有一个
message类型string

如果您在其他地方遇到错误,您可能没有为泛型提供类型,例如,您可能没有为 HTTP 请求的返回值传递类型。

对于unknown类型,在获得 TypeScript 支持之前,我们首先必须检查当前存储在变量中的类型。

当无法提前知道变量存储的内容时,将使用该类型。因此,在访问特定属性或方法之前,我们必须使用类型保护。

索引.ts
const something: unknown = 42; if (typeof something === 'string') { console.log(something.toUpperCase()); } else if (typeof something === 'number') { console.log(something.toFixed(2)); }

例如,您可以检查值的类型以便能够使用内置方法。

索引.ts
async function fetchData() { try { await Promise.resolve(42) } catch (err) { // 👈️ err is unknown if (typeof err === 'object' && err !== null) { console.log(err.toString()); } else { console.log('Unexpected error', err); } } }

我们检查是否err有一种对象,而不是null

检查似乎是随机的null,但我们必须这样做,因为在 JavaScript(和 TypeScript)中null有一个类型。object

索引.ts
console.log(typeof null); // 👉️ "object"
如果err存储一个对象但不是null,我们可以安全地使用特定于对象的内置方法,例如toString()

TypeScript 并不总是将catch块中的错误键入为unknown. 如果您不喜欢这种行为,您可以在您的文件中将该useUnknownInCatchVariables
属性设置为,
以将错误键入为
.
falsetsconfig.jsonany

tsconfig.json文件
{ "compilerOptions": { // ... other stuff "useUnknownInCatchVariables": false } }

如果您在文件中设置useUnknownInCatchVariables,则错误变量将被键入为.falsetsconfig.jsonany

索引.ts
async function fetchData() { try { throw new Error('Something went wrong'); } catch (err) { // 👉️ err is type any console.log(err.message); // ✅ OK console.log(err.anything); // ✅ OK } }

但是,当使用这种方法时,您可能会遇到意外的运行时错误,因为无法确定抛出的是一个Error
实例(尤其是在使用 3rd 方包时)。

结论

当我们尝试访问类型为 的值的属性时,会发生“对象类型未知”错误unknown要解决该错误,请在访问属性之前使用类型保护来缩小对象的类型,例如
if (err instanceof Error) {}.