Problem
I'm writing a package that relies on the fact that decorators will initialize a class object property name.
// index.ts
const Property = (_target: any, key: any) => {
}
class Student {
@Property
name!: string;
age!: number;
}
console.log(Object.getOwnPropertyNames(new Student()) // Outputs ["name"]
I've confirmed that this behavior works by compiling the code to JavaScript. However, when I'm writing tests using Vitest, Object.getOwnPropertyNames(new Student()) returns an empty array.
// index.spec.ts
describe("Test decorator", () => {
class Student {
@Property
name!: string;
}
it("Decorator initalize value", () => {
expect(Object.getOwnPropertyNames(student)).toEqual(
expect.arrayContaining(["name"]) // Fails
);
});
})
Environment
- node:
v20.5.1 - typescript:
v5.3.3
# package.json
{
"devDependencies": {
"ts-node": "^10.9.2",
"typescript": "^5.3.3",
"vitest": "^1.2.0"
}
}
# tsconfig.json
{
"compilerOptions": {
/* Language and Environment */
"target": "ES6" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
/* Modules */
"module": "commonjs" /* Specify what module code is generated. */,
/* Emit */
"declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
/* Interop Constraints */
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
/* Type Checking */
"strict": true /* Enable all strict type-checking options. */,
/* Completeness */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"include": ["src/**/*"],
"exclude": ["src/**/*.spec.ts"]
}
What I've Tried
My initial thought was that tsconfig.json is not properly initialized for Vitest. I tried manually setting the path in vitest.config.ts, but it didn't resolve the problem.
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
typecheck: {
tsconfig: "./tsconfig.json",
},
},
});
I then tried scanning through their documentations and searching online, but haven't found any relevant resources. I'm not sure where else to go from here. I would appreciate any help or suggestions!
I figured out a workaround using Jest. I had to install quite a lot Babel plugin in order to make it work.
I also came across this post, which I believe explain why decorators do not work with Vitest.