为什么打字稿属性装饰器在升级后停止工作?

Kei*_*ith 1 javascript visual-studio typescript tsconfig typescript-decorator

我有一个简单的 TypeScript tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "experimentalDecorators": true,
    ...
Run Code Online (Sandbox Code Playgroud)

以及一个使用装饰器的类:

class MyClass {
    @myDecorator()
    myField: any;
}
Run Code Online (Sandbox Code Playgroud)

装饰器导致myField作为使用函数的属性发出__decorate,该myDecorator函数被传递给它。

升级到最新版本 (4.2.4) 后,它在 Visual Studio 2019 中停止工作,但它继续在 VS Code(使用 4.3.5)和持续集成工具(在 4.3.5 和较旧的 3.* TypeScript 版本中)中工作)。

经过一番调查后发现,发出的 JavaScript 已更改为显式包含这些字段,但仅限于 Visual Studio 2019 中嵌入的 TypeScript 4.2.4。这些显式字段导致__decorate无法创建同名的新属性。

为什么发出的 JS 发生了变化?

我如何解决它?

Kei*_*ith 8

TL;DR:修复升级 TypeScript 时 TypeScript 属性装饰器损坏的方法是将添加"useDefineForClassFields": false到您的tsconfig.json.

这是由于 TypeScript 中的一项重大更改在 3.7 中是可选的,但在 4.2 中似乎是默认设置(但不是 4.3),以及 Visual Studio 2019 中嵌入版本的 TypeScript 忽略设置的方式。

首先,我们有一个新标志:useDefineForClassFields- 打开此标志tsc会直接发出字段。这预计会破坏装饰器,但显然是设计使然(尽管这意味着useDefineForClassFields现在experimentalDecorators会破坏彼此)。

由于useDefineForClassFields这是一个重大更改,它应该默认为false. 但是,为了与 ECMAScript 标准保持一致,它应该默认truetargetisESNextES2020

事实并非如此。它默认为false except在 Visual Studio 中,在 Visual Studio 中默认为true,无论您的tsconfig.