Vitest与编译后JavaScript的装饰器行为不一致问题求助
Vitest测试中装饰器初始化的类属性无法通过
Object.getOwnPropertyNames检测到 问题描述
我开发了一个依赖装饰器初始化类对象属性名的包。将代码编译为JavaScript后,执行Object.getOwnPropertyNames(new Student())会输出["name"];但用Vitest编写测试时,这条语句返回空数组,导致测试用例验证失败。
环境信息
- Node.js: v20.5.1
- TypeScript: v5.3.3
- 相关配置包含在
package.json与tsconfig.json中
已尝试操作
- 在
vitest.config.ts中手动指定tsconfig路径,但问题未解决 - 查阅Vitest及TypeScript文档、搜索相关问题后未找到可行方案
可能的解决方向
1. 对齐Vitest与tsc的装饰器编译逻辑
Vitest默认用esbuild编译代码,而esbuild对TypeScript装饰器的处理逻辑和tsc存在差异。可以强制Vitest使用tsc编译:
// vitest.config.ts import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { transformMode: { web: [/\.[jt]sx$/], }, }, esbuild: { tsconfigRaw: require('./tsconfig.json'), }, });
也可以尝试开启useTsconfigDeclaration: true,确保Vitest完全遵循你的tsconfig配置。
2. 验证装饰器是否在测试环境中执行
在装饰器函数中添加日志,确认它是否在测试运行时被调用:
function InitProperty(target: any, propertyKey: string) { console.log(`装饰器触发:初始化属性${propertyKey}`); Object.defineProperty(target, propertyKey, { value: '', writable: true, enumerable: true, configurable: true, }); } class Student { @InitProperty name!: string; }
如果测试时无日志输出,说明装饰器未被执行,需检查Vitest是否开启了装饰器支持。
3. 确认tsconfig的装饰器配置正确性
确保tsconfig.json中相关配置无误:
{ "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true, "target": "ES2022", "module": "ESNext", "moduleResolution": "NodeNext" } }
即使指定了tsconfig路径,也要确认Vitest是否正确加载了这些配置。
4. 测试编译后的JS文件
如果以上方法无效,可以直接测试编译后的JavaScript文件,排除Vitest编译环节的干扰,确认是环境问题还是装饰器逻辑本身的问题。
内容的提问来源于stack exchange,提问作者Nick Doan
相关产品推荐
相关产品推荐

