🔎 搜索词
decorator, experimentalDecorators, emitDecoratorMetadata, TC39, reflect-metadata, Reflect.metadata(k, v)
🕗 版本与回归信息
当设置禁用实验性装饰器时出现问题
"experimentalDecorators": false,
"emitDecoratorMetadata": false,
⏯ Playground链接
https://github.com/paulsmithkc/typescript-decorators
💻 代码
tsconfig.json
{
"compilerOptions": {
"target": "ES2021",
"module": "commonjs",
"outDir": "dist",
"declaration": true,
"experimentalDecorators": false,
"emitDecoratorMetadata": false
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
src/index.ts
import 'reflect-metadata';
function setting(defaultValue: string): any {
function getType(target: unknown, property: string | symbol) {
return Reflect.getMetadata('design:type', target, property);
}
function settingExperimental(target: unknown, property: string | symbol): void {
console.log('settingExperimental', { defaultValue, target, property, type: getType(target, property) });
target[property] = process.env[String(property)] || defaultValue;
return;
}
function settingTC39(_target: unknown, context: ClassFieldDecoratorContext): () => string {
return function (): string {
console.log('settingTC39', { defaultValue, target: this, context, type: getType(this, context.name) });
return process.env[String(context.name)] || defaultValue;
};
}
return function (target: unknown, context: string | symbol | ClassFieldDecoratorContext) {
if (typeof context !== 'object') {
return settingExperimental(target, context);
} else {
return settingTC39(target, context);
}
};
}
class Config {
@setting('default_1') SETTING_ONE: string;
}
const configInstance = new Config();
运行方式:
tsc --project tsconfig.json && node dist/index.js
🙁 实际行为
Reflect.getMetadata('design:type', target, property)
返回 undefined。
🙂 预期行为
Reflect.getMetadata('design:type', target, property)
在使用标准 TC39 装饰器时,返回类字段的类型。
关于问题的附加信息
- 使用以下方式进行转译时:
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
装饰器 Reflect.metadata("design:type", type)
会自动应用于每个类字段。
- 使用以下方式进行转译时:
"experimentalDecorators": false,
"emitDecoratorMetadata": false,
装饰器 Reflect.metadata("design:type", type)
不会被应用。
- 使用以下方式进行转译时:
"experimentalDecorators": false,
"emitDecoratorMetadata": true,
Typescript 产生以下错误
Option 'emitDecoratorMetadata' cannot be specified without specifying option 'experimentalDecorators'.
7条答案
按热度按时间vyu0f0g11#
据我所知,这个功能尚未实现。请参阅 #53461 。
zd287kbt2#
同样的问题。许多库使用关于类型的元数据,例如Angular、NestJs、class-validator和用于依赖注入的我的库。为新的装饰器生成元数据是非常必要的。
c0vxltue3#
我也遇到了这个问题。这里是操场链接。
我已经将
emitDecoratorMetadata
设置为true
,但发射的代码中不包含desgin:type
元数据。z9smfwbn4#
我认为这个问题的标题需要改成类似于
TC39 Decorators does not emit metadata to Symbol.Metadata
这样的内容。同时,查看代码后发现它似乎没有在这里实现:https://github.com/microsoft/TypeScript/blob/v5.3.3/src/compiler/transformers/ts.ts#L1064yhuiod9q5#
我也认为发射类型元数据是非常必要的,但是现在Decorators和Decorator Metadata已经在TC39中实现了阶段3,并且在TS >=5.2中得到了实现,因此不再考虑在
reflect-metadata
库中提出的API进行标准化。这就是为什么我认为更好的是expose design-time type information in the new TC39 decorator metadata whenemitDecoratorMetadata: true
。watbbzwu6#
我也认为发射类型元数据是非常必要的,但现在Decorators和Decorator Metadata已经在TC39中实现了阶段3,并在TS >=5.2中得到了实现,因此不再考虑将
reflect-metadata
库中提出的API标准化。这就是为什么我认为最好使用expose design-time type information in the new TC39 decorator metadata when
emitDecoratorMetadata: true
的原因。倾向于同意@artberri的意见。我已经为如何实现这一点提出了一个PoC/提案。许多基础已经建立起来,所以这几乎不需要任何更改。
7z5jn7bk7#
Mark nestjs/nest#11414