import "reflect-metadata"
function validate(target: any) {
let paramtypes = Reflect.getMetadata("design:paramtypes", target);
console.log(paramtypes); // undefined
}
@validate
class Log {
constructor(public readonly xx: string) {}
}
Hit me to start the server, and when I opened the webpage, I found that paramtypes was undefined
tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
"include": ["./src"]
}
Vite uses ESBuild which doesn't support "emitDecoratorMetadata"
in tsconfig, since ESBuild doesn't have its own type system implemented. Refer to this vitejs/vite#788 for more details on this topic.
However, there are workarounds to this issue. One approach I took was explicitly disabling ESBuild and used SWC instead. You can find more details regarding that on this demo. Here is its vite config file:
import typescript from "@rollup/plugin-typescript";
import swc from "rollup-plugin-swc";
// import typescript from "rollup-plugin-typescript2";
export default defineConfig({
plugins: [
swc({
jsc: {
parser: {
syntax: "typescript",
// tsx: true, // If you use react
dynamicImport: true,
decorators: true,
},
target: "es2021",
transform: {
decoratorMetadata: true,
},
},
}),
],
esbuild: false,
});
SWC is a fast alternative to ESBuild, having implemented its own type system, it can emit decorator metadata without any issue.