打字稿反映公共/私人

时间:2018-07-08 20:01:32

标签: typescript ecmascript-6 typescript-typings

我有一个假设的课程

class Test {
  @isThisPublic() public test1?: any;
  @isThisPublic() public test2?: any;
}

现在,在@isThisPublic()装饰器中,我想根据它是否是公共类字段来执行其他操作。有办法吗?

谢谢!

2 个答案:

答案 0 :(得分:3)

TypeScript使用emitDecoratorMetadata compiler option发出其他元数据,metadata proposalreflect-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;
}