Typescript TS装饰器:生成编译器可见的属性

Typescript TS装饰器:生成编译器可见的属性,typescript,decorator,Typescript,Decorator,是否可以在属性装饰器中定义一些属性,并让TS编译器理解这些新属性 在下面的代码中,aExtra属性可以通过命名属性访问器v['aExtra']或通过对任何(a).aFieldExtra的强制转换来访问,但不能直接访问v.aExtra,因为编译器没有看到它(属性不存在) 有没有可能让编译器看到这个额外的属性 function withExtra(target: any, fieldName: string) { Object.defineProperty(target, fieldName +

是否可以在属性装饰器中定义一些属性,并让TS编译器理解这些新属性

在下面的代码中,
aExtra
属性可以通过命名属性访问器
v['aExtra']
或通过对任何
(a).aFieldExtra
的强制转换来访问,但不能直接访问
v.aExtra
,因为编译器没有看到它(属性不存在)

有没有可能让编译器看到这个额外的属性

function withExtra(target: any, fieldName: string) {
 Object.defineProperty(target, fieldName + 'Extra', {
    get: function (): String {
      return this[fieldName] + 'Extra'; // <EnumValue[]>this._beanInternalService.getEnumValues(enumType);
    },
    configurable: true,
    enumerable: true
  });
}

class A {
  @withExtra
  a: string;
}

describe('test Extra', () => {
  it('addsExtra', () => {
    const v = new A();
    v.a = 'a';
    expect(v['aExtra']).toEqual('aExtra'); // Works as expected
    expect((<any>v).aExtra).toEqual('aExtra'); // Compiles, but not very nice
    // does not compile :
    // expect(v.aExtra).toEqual('aExtra');
  });
});
函数withExtra(目标:任意,字段名:字符串){
Object.defineProperty(目标,字段名+‘额外’{
get:function():字符串{
返回此[fieldName]+“Extra”;//this.\u beainternalservice.getEnumValues(enumType);
},
对,,
可枚举:true
});
}
甲级{
@额外
a:弦;
}
描述('额外测试',()=>{
它('addsExtra',()=>{
常数v=新的A();
v、 a=‘a’;
expect(v['aExtra'])。toEqual('aExtra');//按预期工作
expect((v).aExtra.toEqual('aExtra');//编译,但不是很好
//不编译:
//expect(v.aExtra)。toEqual(“aExtra”);
});
});

不,装饰程序不会更改TypeScript看到的类的结构。这是有争议的,但这只是一个没有提案的“建议”。即使你有这个,我怀疑你能自动得到你想要的行为,因为添加的属性名是动态的。目前还没有在类型级别追加字符串文本的方法,因此您甚至无法描述正在进行的转换:

// without Append<A extends string, B extends string>, you can't type this:

function appendExtra<T extends string>(originalKey: T): Append<T,'Extra'> {
  return originalKey+'Extra';
}
这当然会被编译器看到


你可以试着用混音代替装饰,但这会更烦人,就像你在问题中所做的演员一样“不好”


希望有帮助!祝你好运。

即使你的答案说今天没有“好”的解决方案,这也会有所帮助。我相信我会手动添加aExtra字段的声明。谢谢你给我这个问题的链接
class A {
  @withExtra
  a: string;
  aExtra: string; //added by decorator
}