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

yc0p9oo0  于 6个月前  发布在  TypeScript
关注(0)|答案(3)|浏览(79)

建议:
为重载方法的实现签名隐式推断参数类型
这个问题是 #7763#34319 的补充

🔍 搜索词

TypeScript 接口的多个签名;
从不同签名中推断参数;
重载方法的实现签名;

✅ 可实施性检查清单

我的建议满足以下准则:

  • 这不会对现有的 TypeScript/JavaScript 代码造成破坏性的更改
  • 这不会改变现有 JavaScript 代码的运行时行为
  • 这可以在不根据表达式的类型生成不同的 JS 的情况下实现
  • 这不是一个运行时特性(例如库功能、带有 JavaScript 输出的非 ECMAScript 语法、JS 的新语法糖等)
  • 这个特性将与 TypeScript's Design Goals 的其他部分保持一致。

⭐ 建议

在某些情况下添加对参数的隐式推断或受限制的推断

📃 动机示例

以前,你可以实现简单的

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
  // ...
}

现在你可以使用

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'
    }
  }
}

💻 用例

防止复杂的类型注解解决方案,简化代码,让 TypeScript 再次听起来!
最好的祝愿。

ev7lccsx

ev7lccsx1#

我非常确定这是一个重复的问题,但我现在无法找到原始问题。

xa9qqrwz

xa9qqrwz2#

这个问题是#7763#34319的补充。实际上,我认为它只是#7763的一个直接复制。

1yjd4xko

1yjd4xko3#

自从#7763(即参数元组)以来,发生了很多变化。我们可以在某个时候重新考虑。

相关问题