[英]Typescript reflect public / private
我有一个假设的 class
class Test {
@isThisPublic() public test1?: any;
@isThisPublic() public test2?: any;
}
现在,在@isThisPublic()
装饰器中,我想根据它是否是公共 class 字段来做不同的事情。 有没有办法做到这一点?
谢谢!
TypeScript使用emitDecoratorMetadata
编译器选项发出其他元数据, emitDecoratorMetadata
选项可用于元数据提议的 reflect-metadata
emitDecoratorMetadata
。
正如提案所述,可以为属性类型,方法参数和方法返回值类型发出设计时元数据。
可见性不在发出的元数据中,因此在运行时它不适用于装饰成员。
由于可见性和装饰器都是由开发人员指定的,因此@isThisPublic()
装饰器不会带来太多好处,因为开发人员可以指定相应的装饰器(无论它们用于什么):
class Test {
@Public test1?: any;
@Private private test2?: any;
}
正如他在回答中提到的那样,在编译器中没有对此的支持。
添加指定字段的公共/私有性质的装饰器是一个不错的选择,但是团队中总有可能开发人员可能不知道装饰的需要而忘记添加它,甚至装饰器和修饰语可能会分歧(是的,它们彼此相邻,但有时候人们会忽略它们),这可能会导致错误。
我们可以以类型安全的方式自己添加此信息的一种方法是使用keyof
仅返回类的公共字段的事实。 使用这个我们可以构建一个函数,该函数只接受具有该类的公共字段的对象。 然后,编译器将强制执行此函数的参数必须包含所有公共字段且仅包含公共字段,并且任何其他字段都将引发错误。
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;
}
我的项目https://typescript-rtti.org/使这成为可能。
import { reflect } from 'typescript-rtti';
class Test {
public test1?: any;
private test2?: any;
protected test3?: any;
}
expect(reflect(Test).getMethod('test1').isPublic).to.be.true;
expect(reflect(Test).getMethod('test2').isPrivate).to.be.true;
expect(reflect(Test).getMethod('test3').isProtected).to.be.true;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.