Node TypeScript 项目报 Cannot find name Performance
Node TypeScript 工程不带 DOM 时,fake-timers 15.3.2 的声明可能报 Performance 未定义。正式 15.4.0 改用包内 PerformanceLike,避免为此放宽整个服务端类型环境。
Node 专用的 TypeScript 项目没有启用 DOM,升级 fake-timers 后却报 Cannot find name 'Performance'。错误位置若在 fake-timers 自带的 d.ts,先检查声明中的浏览器类型引用,不要先把整个后端工程改成浏览器环境。
@sinonjs/fake-timers 15.3.2 的 Timers 类型把 performance 字段写成全局 Performance。只包含 ES 库的类型环境可能没有这个名字;安装环境中的 Node 类型版本和暴露范围也会影响结果。运行时能访问 performance,并不保证 TypeScript 当前装载了同名全局接口。
正式 15.4.0 已不再依赖这个全局名字
15.4.0 的正式声明使用包内定义的 PerformanceLike,提供 now 方法和允许的其他字段,Timers.performance 改为引用它。这个变化针对声明依赖,不要求业务主动把 DOM 加入 lib。
沿项目兼容要求更新真正被失败工作区解析的 fake-timers,然后检查安装目录中的 d.ts。下面这样的 Node 类型配置不应为了修这一处依赖而随意扩大到 DOM:
{
"compilerOptions": {
"lib": ["ES2022"],
"types": ["node"],
"skipLibCheck": false
}
}
这是说明类型环境的片段,应合入现有配置,保留原来的 target、module、moduleResolution 和其他选项;项目需要安装与运行环境相符的 Node 类型。它不是一份可以替换所有工程配置的完整 tsconfig。
加 DOM 与跳过检查各有代价
加入 DOM 会把 document、window 等名字一并带进类型环境,可能掩盖服务端误用浏览器接口。skipLibCheck 则跳过依赖声明内部的一批检查。两者都可能暂时消除报错,但并没有修正这处声明对全局 Performance 的依赖。
如果更新后错误仍在,检查 TypeScript 实际解析到的文件路径:工具链或嵌套依赖可能保留旧副本。也要区分另一个包自身引用 Performance 的情况,不能看到相同名字就认定一定来自 fake-timers。
验收使用原来不带 DOM 的 Node 编译入口,并覆盖测试文件和需要生成的声明。确认没有靠新加全局 any 或放宽检查绕过错误;运行测试时再核对原来的时间模拟行为,类型修复本身不说明所有调度问题也一并修复。


