Repository: TypeScript
Issue: Allow overload signatures to have different access levels
Labels: Suggestion,Awaiting More Feedback

### 🔍 Search Terms

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

### ✅ Viability Checklist

- [X] This wouldn't be a breaking change in existing TypeScript/JavaScript code
- [X] This wouldn't change the runtime behavior of existing JavaScript code
- [X] This could be implemented without emitting different JS based on the types of the expressions
- [X] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- [X] This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- [X] This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals

### ⭐ 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

``` typescript
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
``` typescript
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]'