Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript reflect public / private

I have a hypothetical class

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

Now, in the @isThisPublic() decorator, I want to do different things depending on whether it's a public class field. Is there a way to do this?

Thanks!

like image 292
Yorrd Avatar asked May 19 '26 13:05

Yorrd


2 Answers

TypeScript emits additional metadata with emitDecoratorMetadata compiler option which is available with reflect-metadata polyfill for metadata proposal.

As the proposal states, there can be design-time metadata emitted for property type, method parameter and method return value types.

Visibility is not among emitted metadata, so it's unavailable for decorated members at runtime.

Since both visibility and decorators are specified by a developer, there wouldn't be much benefit from @isThisPublic() decorator, because a developer can specify respective decorators (whatever they are for):

class Test {
  @Public test1?: any;
  @Private private test2?: any;
}
like image 51
Estus Flask Avatar answered May 22 '26 02:05

Estus Flask


As estus mentions in his answer there is no support for this in the compiler.

Adding a decorator specifying the public/private nature of the field is a good option, but there is always potential in a team that a developer might not be aware of the need for the decoration and forget to add it, or even that the decorator and the modifier might diverge (yes they are right next to each other but sometimes people ignore the obvious), which may lead to bugs down the line.

One way we could add this information ourselves in a type safe way, is to use the fact that keyof returns only public fields of the a class. Using this we can build a function that takes an object with only the public fields of the class. The compiler will then enforce that the argument to this function must contain all public fields and only the public fields, and any other field will raise an error.

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;
}
like image 20
Titian Cernicova-Dragomir Avatar answered May 22 '26 03:05

Titian Cernicova-Dragomir



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!