diff --git a/napi/transform/index.d.ts b/napi/transform/index.d.ts index 7b65ff4114555..efa72c3048b57 100644 --- a/napi/transform/index.d.ts +++ b/napi/transform/index.d.ts @@ -31,6 +31,16 @@ export interface DecoratorOptions { * @default false */ legacy?: boolean + /** + * Enables emitting decorator metadata. + * + * This option the same as [emitDecoratorMetadata](https://www.typescriptlang.org/tsconfig/#emitDecoratorMetadata) + * in TypeScript, and it only works when `legacy` is true. + * + * @see https://www.typescriptlang.org/tsconfig/#emitDecoratorMetadata + * @default false + */ + emitDecoratorMetadata?: boolean } export interface ErrorLabel { diff --git a/napi/transform/src/transformer.rs b/napi/transform/src/transformer.rs index 7cb29f88dbe46..02e18e5109e69 100644 --- a/napi/transform/src/transformer.rs +++ b/napi/transform/src/transformer.rs @@ -278,13 +278,22 @@ pub struct DecoratorOptions { /// @see https://www.typescriptlang.org/tsconfig/#experimentalDecorators /// @default false pub legacy: Option, + + /// Enables emitting decorator metadata. + /// + /// This option the same as [emitDecoratorMetadata](https://www.typescriptlang.org/tsconfig/#emitDecoratorMetadata) + /// in TypeScript, and it only works when `legacy` is true. + /// + /// @see https://www.typescriptlang.org/tsconfig/#emitDecoratorMetadata + /// @default false + pub emit_decorator_metadata: Option, } impl From for oxc::transformer::DecoratorOptions { fn from(options: DecoratorOptions) -> Self { oxc::transformer::DecoratorOptions { legacy: options.legacy.unwrap_or_default(), - emit_decorator_metadata: false, + emit_decorator_metadata: options.emit_decorator_metadata.unwrap_or_default(), } } } diff --git a/napi/transform/test/transform.test.ts b/napi/transform/test/transform.test.ts index 61b287e109ff3..61ae68beaa2ef 100644 --- a/napi/transform/test/transform.test.ts +++ b/napi/transform/test/transform.test.ts @@ -276,4 +276,41 @@ describe('legacy decorator', () => { " `); }); + + describe('emitDecoratorMetadata', () => { + it('matches output', () => { + const code = ` + export default @dce class C { + @dce + prop = 0; + method(@dce param) {} + } + `; + const ret = transform('test.tsx', code, { + decorator: { + legacy: true, + emitDecoratorMetadata: true, + }, + }); + expect(ret.code).toMatchInlineSnapshot(` + "import _decorateMetadata from "@oxc-project/runtime/helpers/decorateMetadata"; + import _decorate from "@oxc-project/runtime/helpers/decorate"; + import _decorateParam from "@oxc-project/runtime/helpers/decorateParam"; + let C = class C { + prop = 0; + method(param) {} + }; + _decorate([dce, _decorateMetadata("design:type", Object)], C.prototype, "prop", void 0); + _decorate([ + _decorateParam(0, dce), + _decorateParam(0, _decorateMetadata("design:type", Function)), + _decorateParam(0, _decorateMetadata("design:paramtypes", [Object])), + _decorateParam(0, _decorateMetadata("design:returntype", void 0)) + ], C.prototype, "method", null); + C = _decorate([dce], C); + export default C; + " + `); + }); + }); });