我有一个假设的课程
class Test {
@isThisPublic() public test1?: any;
@isThisPublic() public test2?: any;
}
现在,在@isThisPublic()
装饰器中,我想根据它是否是公共类字段来执行其他操作。有办法吗?
谢谢!
答案 0 :(得分:3)
TypeScript使用emitDecoratorMetadata
compiler option发出其他元数据,metadata proposal的reflect-metadata
polyfill可以使用。
该提案指出,可能会针对属性类型,方法参数和方法返回值类型发出设计时元数据。
可见性不在发出的元数据中,因此装饰成员在运行时不可用。
由于可见性和装饰器都是由开发人员指定的,因此@isThisPublic()
装饰器不会带来太多好处,因为开发人员可以指定各自的装饰器(无论它们用于什么):
class Test {
@Public test1?: any;
@Private private test2?: any;
}
答案 1 :(得分:1)
正如estus在他的回答中提到的那样,编译器不支持此功能。
添加指定该字段的公共/私有性质的装饰器是一个不错的选择,但是团队中总是存在这样的可能性,即开发人员可能没有意识到装饰的必要性而忘记添加装饰,甚至装饰器和修饰符可能会发散(是的,它们彼此相邻,但有时人们会忽略明显的事物),这可能会导致错误。
我们可以通过类型安全的方式自己添加此信息的一种方法是利用keyof
仅返回a类的公共字段这一事实。使用此函数,我们可以构建一个仅包含类的公共字段的对象的函数。然后,编译器将强制该函数的参数必须包含所有公共字段,并且仅包含公共字段,其他任何字段都将引发错误。
function isPublicMetadata<T>(publicFields: Record<keyof T, true>){
return publicFields;
}
const publicTestFields = isPublicMetadata<Test>({
test1: true
// test2 : true // this is an error
})
class Test {
test1?: any;
private test2?: any;
}