TypeScript
Oxc 转换器支持将 TypeScript 转换为 JavaScript。
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 在处理未使用导入时的语义与 JavaScript 规范不同。[verbatimModuleSyntax](https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax) 选项可使 TypeScript 与 JavaScript 规范保持一致。
如果你使用此选项,请确保将 typescript.onlyRemoveTypeImports 选项设置为 true。
import { transform } from "oxc-transform";
const result = await transform("lib.ts", sourceCode, {
typescript: {
onlyRemoveTypeImports: true,
},
});useDefineForClassFields
TypeScript 早期对于类字段的语义与 JavaScript 规范不同。useDefineForClassFields 选项可让 TypeScript 与 JavaScript 规范保持一致。如果 tsconfig 中的 target 选项设置为 es2022 或更高版本,则该选项默认启用。
如果你禁用此选项,请确保将 typescript.removeClassFieldsWithoutInitializer 选项和 assumptions.setPublicClassFields 设置为 true。
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 选项。
import { transform } from "oxc-transform";
const result = await transform("lib.ts", sourceCode, {
decorators: {
legacy: true,
emitDecoratorMetadata: true,
},
});装饰器元数据:需要类型推断的类型将回退到 Object
由于缺乏完整的类型推断功能,当 Oxc 转换器无法计算装饰器元数据的类型时,会回退到 Object 类型。
例如,以下代码将被转换为如下代码:
import { Something1 } from "./somewhere";
type Something2 = Exclude<string | number, string>;
export class Foo {
@test
foo(input1: Something1, input2: Something2) {}
}// 省略辅助函数
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,
);// 省略辅助函数
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 显式设置类型:
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) {}
}// 省略辅助函数
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 选项。
import { transform } from "oxc-transform";
const result = await transform("lib.ts", sourceCode, {
typescript: {
rewriteImportExtensions: "rewrite", // 或 "remove"
},
});注意事项
独立模块
由于 Oxc 转换器独立地转换每个文件,某些 TypeScript 功能不被支持。
为避免使用不受支持的功能,你应该在 tsconfig.json 文件中启用 isolatedModules 选项。
部分命名空间支持
TypeScript 具有名为 命名空间 的遗留功能。尽管建议新项目使用 ES 模块,但 Oxc 转换器对命名空间具有部分支持。
不支持使用 var 或 let 导出变量
使用 var 或 let 导出变量不被支持。
namespace Foo {
export let bar = 1;
}
console.log(Foo.bar);一种解决方法是使用 const。如果需要变量可变,可以使用带有内部可变性的对象:
namespace Foo {
export const bar = { value: 1 };
}
console.log(Foo.bar.value);同名命名空间之间不共享作用域
namespace Foo {
export const bar = 1;
}
namespace Foo {
export const baz = bar;
}let foo;
(function (_Foo) {
const bar = (_Foo.bar = 1);
})(Foo || (Foo = {}));
(function (_Foo2) {
const baz = (_Foo2.baz = bar);
})(Foo || (Foo = {}));var Foo;
(function (Foo) {
Foo.bar = 1;
})(Foo || (Foo = {}));
(function (Foo) {
Foo.baz = Foo.bar;
})(Foo || (Foo = {}));在此示例中,第二条命名空间中的 bar 引用指向第一个命名空间中的 bar 变量(TypeScript 编译器输出),但在 Oxc 转换器输出中并不如此。
一种解决方法是显式通过命名空间对象引用:
namespace Foo {
export const bar = 1;
}
namespace Foo {
export const baz = Foo.bar;
}