microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.36k stars 12.41k forks source link

Feat: infer parameter types for the implementation signature of an overloaded method #55236

Open ryuujo1573 opened 1 year ago

ryuujo1573 commented 1 year ago

Suggestion

implicitly infer parameter types for the implementation signature of an overloaded method This issue is a complement to #7763, #34319

🔍 Search Terms

TypeScript interface with multiple signatures; infer params from different signatures; implementation signature of an overloaded method;

✅ Viability Checklist

My suggestion meets these guidelines:

⭐ Suggestion

Add an implicit inference to the params or restricted inference in some cases

📃 Motivating Example

Before, you can achieve simple

class Some {
  async request(action: 'auth', payload: AuthPayload): Promise<AuthResponse>
  async request(action: 'pub', payload: PubPayload): Promise<PubResponse>
  async request<S extends Values<SignalingRequests>>(
    ...params: Parameters<S>
  ): Promise<ReturnType<S>> {
    const [action, payload] = params
    switch (action) { /* ... */ }
  }
}
// redundant declarations
// declare Values<T> = T[keyof T]
declare type SignalingRequests = {
  auth: (action: 'auth', payload: AuthPayload) => AuthResponse
  pub: (action: 'pub', payload: PubPayload) => PubResponse
  // ...
}

Now you can use

class Some {
  async request(action: 'auth', payload: AuthPayload): Promise<AuthResponse>
  async request(action: 'pub', payload: PubPayload): Promise<PubResponse>
  async request(...params) {
    if (params[0] == 'auth') {
      const p: AuthPayload = params[1] // this works
    }
    // or you can write:
    const [action, payload] = params
    switch (action) {
      case 'auth':
        payload // AuthPayload
        break
      case 'pub':
        break
      default:
        // exhaustive check
        const nope: never = action
        throw 'nope'
    }
  }
}

💻 Use Cases

Prevent complex type annotation workarounds, simplify codes, make TypeScript sound again!

Best regards.

fatcerberus commented 1 year ago

I’m pretty sure this is a duplicate but I can’t find the original issue(s) at the moment.

fatcerberus commented 1 year ago

This issue is a complement to https://github.com/microsoft/TypeScript/issues/7763, https://github.com/microsoft/TypeScript/issues/34319

Actually I think it's just a straight-up dupe of #7763.

RyanCavanaugh commented 1 year ago

A lot has changed since #7763 (namely, parameter tuples). We can reconsider at some point