DEV Community

Chris Cook
Chris Cook

Posted on • Updated on

How To Access Private Class Members in TypeScript

I know we shouldn't access private class members. But sometimes, there is simply no way around. For instance, during unit tests we can access private members to assert the correct values. Or while debugging we want to log a private property to the console.

In TypeScript there are two ways to do this. The first option is to cast the object to any. The problem with this option is that you loose type safety and intellisense autocompletion. The second option is the intentional escape hatch. This is a bug (or feature?) in Typescript which was left open for this very purpose. It allows access to private members via bracket notation while maintaining type safety and autocompletion.

class Test {
    public foo: string = "Foo";
    private bar: string = "Bar";
    public constructor() { }
}

const test = new Test();

// cast as any
console.log((test as any).bar)

// intentional escape hatch
console.log(test['bar'])
Enter fullscreen mode Exit fullscreen mode

Check it yourself at TypeScript Playground.

Top comments (3)

Collapse
 
benhultin profile image
ben hultin • Edited

Accesing private properties even for testing purposes I would not recommend.

Testing private properties should be through the public methods / functions which those interact with the private property to achieve the final outcome.

This is the point of integration testing which verifies the flow from start to finish involving multiple methods working together.

Note: as you mentioned about refraining from using any, the second method still makes use of any. As the phrase goes, "anything is better than any"

Collapse
 
sleepwalker profile image
Sviatoslav

And what about unit testing? What about mocking?

What if your private method makes a plenty of things, including db requests. You have already tested that behavior. Should you re-test this behavior in every test case or it's better to just mock that function to simplify the things? What's the value of complicating all the things around?

Collapse
 
sleepwalker profile image
Sviatoslav • Edited

One possible solution would be to split private logic into separate class or function-module so that function alone will be public but private inside the class you are testing.

This way you can legally mock that function during test. But... it still complicates the things. This looks like "go to solution from books" but in real world the benefit not that big comparing to additional complexity it creates for a project.

Another one solution is to use protected instead of private. This way you can create subclass for tests where this method will be public. But it's still messy and provides no additional value.