简体   繁体   English

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

[英]Why have typescript property decorators stopped working after an upgrade?

I have a simple TypeScript tsconfig.json :我有一个简单的 TypeScript tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "experimentalDecorators": true,
    ...

And a class that uses a decorator:还有一个使用装饰器的 class:

class MyClass {
    @myDecorator()
    myField: any;
}

The decorator causes myField to be emitted as a property that uses a __decorate function, the myDecorator function is passed to it.装饰器导致myField作为使用__decorate function 的属性发出, myDecorator function 被传递给它。

After upgrading to the latest version (4.2.4) this stopped working in Visual Studio 2019, but it continues to work in VS Code (using 4.3.5) and continuous integration tools (in both 4.3.5 and older 3.* TypeScript releases).升级到最新版本 (4.2.4) 后,它在 Visual Studio 2019 中停止工作,但它继续在 VS Code(使用 4.3.5)和持续集成工具(在 4.3.5 和更早的 3.* TypeScript 版本中)工作).

After some investigation it appears that the emitted JavaScript has changed to include the fields explicitly, but only in the TypeScript 4.2.4 embedded in Visual Studio 2019. These explicit fields cause the __decorate to fail to create the new property with the same name.经过一些调查后,似乎发出的 JavaScript 已更改为显式包含字段,但在 Visual Studio 2019 中嵌入的 TypeScript 4.2.4 中。这些显式字段导致__decorate无法创建具有相同名称的新属性。

Why has the emitted JS changed?为什么发出的 JS 发生了变化?

How do I fix it?我如何解决它?

TL;DR : The fix for TypeScript property decorators breaking when you upgrade TypeScript is to add "useDefineForClassFields": false to your tsconfig.json . TL;DR :升级 TypeScript 时 TypeScript 属性装饰器中断的修复是将"useDefineForClassFields": false添加到您的tsconfig.json

This is due to a breaking change in TypeScript that was optional in 3.7, but appears to be the default in 4.2 (but not 4.3), and the way the embedded version of TypeScript in Visual Studio 2019 ignores settings.这是由于 TypeScript 中的重大更改在 3.7 中是可选的,但在 4.2 中似乎是默认设置(但不是 4.3),以及 Visual Studio 2019 中嵌入版本 TypeScript 忽略设置的方式。

Firstly we have a new flag: useDefineForClassFields - turning this on causes tsc to emit fields directly.首先,我们有一个新标志: useDefineForClassFields - 打开它会导致tsc直接发出字段。 This is expected to break decorators, but is apparently by design (even though it means useDefineForClassFields and experimentalDecorators now break each other).预计这会破坏装饰器,但显然是设计使然(即使这意味着useDefineForClassFieldsexperimentalDecorators现在会相互破坏)。

As useDefineForClassFields is a breaking change it's supposed to default to false .由于useDefineForClassFields是一项重大更改,因此它应该默认为false However, to align with the ECMAScript standard it should default to true when target is ESNext or ES2020 .但是,为了与 ECMAScript 标准保持一致, targetESNextES2020时,它应该默认为true

It doesn't.它没有。 It defaults to false except in Visual Studio, where it defaults to true , regardless of your tsconfig .它默认为false除了在 Visual Studio 中,它默认为true ,不管你的tsconfig

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM