question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Explain why private and protected members in a class affect their compatibility

See original GitHub issue

TypeScript Version: up to 2.5.2 at least

In the doc a short paragraph explains that private and protected members in a class affect their compatibility.

I have been searching for a while in the design goals, on SO etc… but could not find a decent explanation of the rationale. Could we:

  • either document the rationale (in the paragraph above?
  • or consider evolving the language?

Note: I found one rationale close to what I am looking for, but you could imagine that the language “reserves” the private names but does not compel to use them.

Code This behavior is especially an issue in unit testing where you want to mock a class, disregarding its internals…

class MyClass {
    pubfield = 0;
    private privfield1 = 0;
    constructor(private privfield2: number) {}
    private method(): void {}
}

class MyClassMock implements MyClass {
    pubfield: number;
    // *** compile errors on missing properties ***
}

Expected behavior: I would like to only care about the public contract that a class-under-test can possibly use from my mock.

Actual behavior: I cannot limit my mock to the public fields.

The ugly workaround I found is the following:

class MyClass {
    pubfield = 0;
    private privfield1? = 0;
    private privfield2? = 0;
    // do not use the shortcut notation because the constructor param is not optional!
    constructor(privfield2: number) {
        this.privfield2 = privfield2;
    }
    private method?(): void {}
}

class MyClassMock implements MyClass {
    pubfield: number;
}

What I do not like is that I have to modify the semantics of my class to be able to mock it and that I am scared that a future overzealous refactoring may use the shortcut notation for fields declaration in the constructor… making the constructor param optional (!)

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:31
  • Comments:27 (17 by maintainers)

github_iconTop GitHub Comments

23reactions
tao-cumplidocommented, Oct 12, 2018

@renatomariscal @jandsu You can create such a type easily yourself with keyof, it only picks the public members.

type Public<T> = { [P in keyof T]: T[P] }
10reactions
RyanCavanaughcommented, Sep 15, 2017

Allowing the private fields to be missing would be an enormous problem, not some trivial soundness issue.

Consider this code:

class Identity {
  private id: string = "secret agent";
  public sameAs(other: Identity) {
    return this.id.toLowerCase() === other.id.toLowerCase();
  }
}

class MockIdentity implements Identity {
  public sameAs(other: Identity) { return false; }
}

MockIdentity is a public-compatible version of Identity but attempting to use it as one will crash in sameAs when a non-mocked copy interacts with a mocked copy.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Difference between Private and Protected in C++ with ...
Protected members enhanced access for derived classes. Only the member functions or the friend functions are allowed to access the private data ...
Read more >
Are protected members part of the public API?
Yes, and yes: protected members are part of the exported (public) API and share the same compatibility requirements.
Read more >
17.5 — Inheritance and access specifiers
With private inheritance, all members from the base class are inherited as private. This means private members are inaccessible, and protected ...
Read more >
Documentation - Type Compatibility
Private and protected members in a class affect their compatibility. When an instance of a class is checked for compatibility, if the target...
Read more >
The difference between struct and class in C++
Though classes defined using either keyword can have public , private and protected base classes and members, the default choice for classes ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found