microsoft / microsoft/TypeScript

Allow overload signatures to have different access levels

Open
#58,316 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Awaiting More Feedback Suggestion
Dominant language
Go
Stars
111k
Forks
14.4k
Avg merge
1d 19h
Merged PRs (30d)
117

Description

🔍 Search Terms

error TS2385: Overload signatures must all be public, private or protected

✅ Viability Checklist
⭐ Suggestion

What I would like to achieve with that is, that tsc checks, that I can only call public signatures from outside of a class, while I can also call private signatures from inside the class and protected ones from inside a child class.

Originally posted by @0815fox in https://github.com/microsoft/TypeScript/issues/7577#issuecomment-214605484

See also the full posts below:
https://github.com/microsoft/TypeScript/issues/7577#issuecomment-214605484
https://github.com/microsoft/TypeScript/issues/58303

📃 Motivating Example
export default class NetworkService<R, G = undefined, Q = G, D = Q, RD=R> {
  get(query?: Q|null): Promise<AxiosResponse<R>>
  get(param: G|null, query: Q|null): Promise<AxiosResponse<R>>;
  protected get(param?: G|Q|null, query?: Q|null): Promise<AxiosResponse<R>>;
  async get(params?: G|Q|null, query?: Q|null): Promise<AxiosResponse<R>> {
  }
 }
 export default class FCNetworkService<R, G=undefined, Q=G, D=Q, RD=R> extends NetworkService<R,G,Q,D,RD> {
    override async get(params?: G|Q|null, query?: Q|null) {
        const result = await super.get(params, query);
    }
}

If I don't add an extra line

get(param?: G|Q|null, query?: Q|null): Promise<AxiosResponse<R>>;

I get the error
"Argument of type 'G | Q | null | undefined' is not assignable to parameter of type 'G | null'."

But that function signature should not be ever called from the outside because the function body cannot tell if params is actually a query object if the second input is undefined, which is why I have the restriction on the second overlord. That is why I need protected for the third overload.

💻 Use Cases
  1. What do you want to use this for? For generic class inheritance overloaded functions override
  2. What shortcomings exist with current approaches? When inheriting and overriding the function with overload signatures, the final combined signature must be provided for the override to call the super method but that signature should not be exposed because it may contain input patterns that logic of the function cannot distinguish.
  3. What workarounds are you using in the meantime? I disable the error on the super method call with @ts-ignore without adding the extra signature needed. If parent changes API later on, the child will fail to detect the change
    super.method.apply doesn't work because I get
    Argument of type 'IArguments' is not assignable to parameter of type '[params: G | null, data: D]'

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No source file or test is named. Start with the TS2385 diagnostic and the overload access-level checking behavior, then read the linked discussions for the intended rules. Done means valid overloads can use different access levels while calls from outside, inside, and derived classes respect those levels.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.