Skip to content

TypeScript

Oxc 변환기는 TypeScript를 JavaScript로 변환하는 기능을 지원합니다.

js
import { transform } from "oxc-transform";

const result = await transform("lib.ts", sourceCode, {
  typescript: {
    jsxPragma: "React.createElement",
    jsxPragmaFrag: "React.Fragment",
    onlyRemoveTypeImports: false,
    allowNamespaces: true,
    removeClassFieldsWithoutInitializer: false,
    rewriteImportExtensions: false,
  },
});

verbatimModuleSyntax

기본적으로, TypeScript는 자바스크립트 사양과 다른 방식으로 사용되지 않는 임포트를 제거합니다.
verbatimModuleSyntax 옵션은 TypeScript가 자바스크립트 사양에 맞추도록 지시합니다.

이 옵션을 사용하는 경우, typescript.onlyRemoveTypeImports 옵션을 true로 설정해야 합니다.

js
import { transform } from "oxc-transform";

const result = await transform("lib.ts", sourceCode, {
  typescript: {
    onlyRemoveTypeImports: true,
  },
});

useDefineForClassFields

TypeScript는 과거에 자바스크립트 사양과 다른 클래스 필드의 의미 체계를 사용했습니다. useDefineForClassFields 옵션은 이를 자바스크립트 사양에 맞추도록 지시합니다. 이 옵션은 tsconfig에서 target 옵션이 es2022 이상으로 설정된 경우 기본적으로 활성화됩니다.

이 옵션을 비활성화하는 경우, typescript.removeClassFieldsWithoutInitializer 옵션과 assumptions.setPublicClassFields를 모두 true로 설정해야 합니다.

js
import { transform } from "oxc-transform";

const result = await transform("lib.ts", sourceCode, {
  typescript: {
    removeClassFieldsWithoutInitializer: true,
  },
  assumptions: {
    setPublicClassFields: true,
  },
});

데코레이터

Oxc 변환기는 레거시 데코레이터를 변환하는 기능을 지원합니다. 이것은 TypeScript에서 실험적 데코레이터라고 불립니다.

tsconfig 파일에서 experimentalDecorators 옵션을 사용하는 경우, decorators.legacy 옵션을 사용할 수 있습니다.
tsconfig 파일에서 emitDecoratorMetadata 옵션을 사용하는 경우, decorators.emitDecoratorMetadata 옵션을 사용할 수 있습니다.

js
import { transform } from "oxc-transform";

const result = await transform("lib.ts", sourceCode, {
  decorators: {
    legacy: true,
    emitDecoratorMetadata: true,
  },
});

데코레이터 메타데이터: 타입 추론이 필요한 타입은 Object로 대체됨

전체 타입 추론 기능이 부족한 관계로, Oxc 변환기가 데코레이터 메타데이터의 타입을 계산할 수 없으면 Object 타입으로 대체합니다.

예를 들어, 다음 코드는 다음과 같이 변환됩니다:

ts
import { Something1 } from "./somewhere";

type Something2 = Exclude<string | number, string>;

export class Foo {
  @test
  foo(input1: Something1, input2: Something2) {}
}
js
// helper 함수 생략
import { Something1 } from "./somewhere";
var _ref;
export class Foo {
  foo(input1, input2) {}
}
_decorate(
  [
    test,
    _decorateMetadata("design:type", Function),
    _decorateMetadata("design:paramtypes", [
      typeof (_ref = typeof Something1 !== "undefined" && Something1) === "function"
        ? _ref
        : Object,
      Object, 
    ]),
    _decorateMetadata("design:returntype", void 0),
  ],
  Foo.prototype,
  "foo",
  null,
);
js
// helper 함수 생략
var _a;
import { Something1 } from "./somewhere";
export class Foo {
  foo(input1, input2) {}
}
__decorate(
  [
    test,
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [
      typeof (_a = typeof Something1 !== "undefined" && Something1) === "function" ? _a : Object,
      Number, 
    ]),
    __metadata("design:returntype", void 0),
  ],
  Foo.prototype,
  "foo",
  null,
);

이 동작은 외부 타입을 사용할 때 TypeScript의 동작과 일치합니다.

명시적으로 타입을 지정하려면 Reflect.metadata를 호출하면 됩니다:

ts
import { Something1 } from "./somewhere";

type Something2 = Exclude<string | number, string>;

export class Foo {
  @test
  @Reflect.metadata("design:paramtypes", [Something1, Number])
  foo(input1: Something1, input2: Something2) {}
}
js
// helper 함수 생략
import { Something1 } from "./somewhere";
var _ref;
export class Foo {
  foo(input1, input2) {}
}
_decorate(
  [
    test,
    Reflect.metadata("design:paramtypes", [Something1, Number]),
    _decorateMetadata("design:type", Function),
    _decorateMetadata("design:paramtypes", [
      typeof (_ref = typeof Something1 !== "undefined" && Something1) === "function"
        ? _ref
        : Object,
      Object,
    ]),
    _decorateMetadata("design:returntype", void 0),
  ],
  Foo.prototype,
  "foo",
  null,
);

TSX

TSX 파일의 변환도 지원됩니다.
자세한 정보는 JSX 변환을 참고하세요.

임포트 확장자 재작성

tsconfig 파일에서 rewriteImportExtensions 옵션을 사용하는 경우, typescript.rewriteImportExtensions 옵션을 사용할 수 있습니다.

js
import { transform } from "oxc-transform";

const result = await transform("lib.ts", sourceCode, {
  typescript: {
    rewriteImportExtensions: "rewrite", // 또는 "remove"
  },
});

주의사항

고립된 모듈

Oxc 변환기는 각 파일을 독립적으로 변환하기 때문에, 일부 TypeScript 기능은 지원되지 않습니다.
지원되지 않는 기능을 사용하지 않기 위해, tsconfig.json 파일에 isolatedModules 옵션을 활성화해야 합니다.

부분적인 네임스페이스 지원

TypeScript는 네임스페이스라는 구식 기능을 가지고 있습니다. 새 프로젝트에서는 모듈 사용을 권장하지만, Oxc 변환기는 네임스페이스에 대해 부분적으로 지원합니다.

var 또는 let으로 변수 내보내기 지원 안 됨

var 또는 let으로 변수를 내보내는 것은 지원되지 않습니다.

ts
namespace Foo {
  export let bar = 1; 
}
console.log(Foo.bar);

대안으로 const를 사용하세요. 변수를 변경 가능하게 하고 싶다면 내부 가변성을 가진 객체를 사용하세요:

ts
namespace Foo {
  export const bar = { value: 1 }; 
}
console.log(Foo.bar.value);

같은 이름의 네임스페이스 간 범위 공유 안 됨

ts
namespace Foo {
  export const bar = 1;
}
namespace Foo {
  export const baz = bar;
}
js
let foo;
(function (_Foo) {
  const bar = (_Foo.bar = 1);
})(Foo || (Foo = {}));
(function (_Foo2) {
  const baz = (_Foo2.baz = bar); 
})(Foo || (Foo = {}));
js
var Foo;
(function (Foo) {
  Foo.bar = 1;
})(Foo || (Foo = {}));
(function (Foo) {
  Foo.baz = Foo.bar; 
})(Foo || (Foo = {}));

이 예제에서 두 번째 네임스페이스의 bar 참조는 TypeScript 컴파일러 출력에서는 첫 번째 네임스페이스의 bar 변수를 가리키지만, Oxc 변환기 출력에서는 그렇지 않습니다.

대안으로 네임스페이스 객체를 명시적으로 참조하면 됩니다:

ts
namespace Foo {
  export const bar = 1;
}
namespace Foo {
  export const baz = Foo.bar; 
}