ste*_*cho 17 node.js typescript
router.get('/cells', async (req, res) => {
try {
const result = await fs.readFile(fullPath, { encoding: 'utf-8' });
res.send(JSON.parse(result));
} catch (err) {
if (err.code === 'ENOENT') { // Object is of type 'unknown'.ts(2571) (local var) err: unknown
await fs.writeFile(fullPath, '[]', 'utf-8');
res.send([]);
} else {
throw err;
}
}
Run Code Online (Sandbox Code Playgroud)
err.code犯这个 ts 错误:Object is of type 'unknown'.ts(2571)
我肯定知道它存在,所以我想知道如何定义?err.code的类型(或接口)err
(tsc版本信息:我的全局打字稿版本是v4.3.5,上面的代码属于我的项目,该项目有打字稿v4.1.2)
- - 编辑 - -
我终于知道为什么这个错误发生在我身上了。我以为我用的是4.3.x下的tsc版本,结果发现我用的是v4.4.x。
在 vscode 中,cmd + shift + P搜索选择 Typescript 版本,我实际上使用了 v4.4.3,(我错误地想到了版本,因为我只从终端检查 tsc 版本)
感谢分享YouTube 视频,
tsa*_*h86 29
就在最近,Typescript 已更新,将错误对象替换为catchbeunknown内部any
这意味着,您的代码对于编译器来说看起来像这样
catch(e: unknown) {
// your logic
}
Run Code Online (Sandbox Code Playgroud)
提供您自己的接口并保存到另一个变量中以避免此错误:
catch(e : unknown) {
const u = e as YourType
// your logic
}
Run Code Online (Sandbox Code Playgroud)
您仍然可以any在那里使用,但不建议这样做。
正如其他答案中所述,从 TypeScript 4.4 开始,错误会自动转换为未知,因此如果不进行类型检查,您将无法对它们执行任何操作。不幸的是,ErrnoExceptions 不是作为可导入类实现的,而只是插入了附加属性的常规错误。它是 @types/node 中的类型接口,但您不能使用isinstance它来检查它,因为没有为此的类定义确切的错误,因此检查isinstance不会Error让您访问该err.code属性。话虽这么说,你可以让编译器满意:
try {
await fs.readFile(file);
catch (err: NodeJS.ErrnoException) {
if (err?.code === 'ENOENT') return;
else throw err;
}
Run Code Online (Sandbox Code Playgroud)
这里需要注意的是,如果您只是执行if (err.code)...并忘记了?,编译器不会抱怨,但您可能会遇到运行时错误。?除非 err 为 null/未定义,否则这种情况极不可能发生,但它仍然不是完全类型安全的,因为理论上您可能会忘记并获得运行时错误。这里的问题是你告诉编译器你知道错误是什么,而实际上错误可能是任何东西(这是自动将错误转换为未知的动机)。
您也可以这样做catch (err: any),但您不会获得代码的任何类型提示,并且如果您忘记在属性上使用安全访问器,您仍然会遇到相同的问题code。解决这个问题没有特别简单的方法,因为您不能简单地在unknown这样的类型上使用安全访问器:if (err?.code === 'ENOENT') return;。我不太清楚为什么,也许他们会在以后的版本中添加这个,但无论哪种方式,我最喜欢的处理这些 fs 错误的方法是编写一个 typeguard 辅助函数,如下所示:
function isErrnoException(e: unknown): e is NodeJS.ErrnoException {
if ('code' in (e as any)) return true;
else return false;
}
Run Code Online (Sandbox Code Playgroud)
然后你的 catch 块是这样的:
try {
await fs.readFile(file);
} catch (err) {
// writing err.code here after the typeguard call satisfies the compiler and is SAFE because we already checked the member exists in the guard function.
if (isErrnoException(err) && err.code === 'ENOENT') return;
else throw err;
}
Run Code Online (Sandbox Code Playgroud)
这至少会检查错误对象是否与 ErrnoException 类似,因为它有一个code属性。您可以更具体地测试所有 ErrnoException 属性是否存在,以真正确保它是 ErrnoException。
| 归档时间: |
|
| 查看次数: |
25951 次 |
| 最近记录: |