搜索词
重载推断函数运算符参数返回值
建议
// Already possible
type ValueForKey<T, K extends keyof T> = T[K];
// Proposal
type Callable = (...args: any[]) => any;
type ValueForArguments<T extends Callable, A extends paramsof T> = T(...A);
用例
这是一个建议,它将有助于解决重载函数问题,如 #26591 ,并将帮助我的 type testing library 能够支持检查,如 expectTypeOf(fn).toBeCallableWith(args)
。
请注意,尽管 ValueForKey
可以实现为:
type ValueForKey<T, K extends keyof T> =
T extends {[Key in K]: infer U} ? U : never;
以下仅适用于非重载函数:
type ValueForArguments<T extends Callable, P extends Parameters<T>> =
T extends (...args: P) => infer R ? R : never;
因为从 Parameters<T>
的推断和类型定义都将只考虑其中一个重载。
我所要求的是让 paramsof
和 T(A1, A2, ...A)
类型语法能够正确地与重载函数一起使用,而不是让推断考虑多个重载。
示例
interface OverloadedFunction {
(arg: number): number;
(arg: string): string;
}
// `number`
type Result1 = OverloadedFunction(number);
// `number | string`
type Result2 = OverloadedFunction(number | string);
// `[number] | [string]`
type Result3 = paramsof OverloadedFunction;
// `number | string`
type Result4 = OverloadedFunction(...paramsof OverloadedFunction)
另外
鉴于上述情况,也有一些像这样的东西是有意义的:
type Newable = new (...args: any[]) => any;
type ValueForArguments<T extends Newable, A extends paramsof new T> = new T(...A);
其中 new T
将 T
的构造函数类型转换为函数类型
检查清单
我的建议满足以下准则:
- 这不会对现有的 TypeScript/JavaScript 代码造成破坏性更改
- 这不会改变现有 JavaScript 代码的运行时行为
- 这可以在不根据表达式的类型发出不同的 JS 的情况下实现
- 这不是一个运行时特性(例如库功能、JavaScript 输出的非 ECMAScript 语法等)
- 这个特性将与 TypeScript's Design Goals 的其他部分保持一致。
8条答案
按热度按时间e4eetjau1#
请注意,尽管ValueForKey可以实现为:
但我不得不收回这个声明,因为我发现了一个目前不起作用的例子。
这意味着
T[...]
语法提供了其他方式无法产生的唯一语义。q5lcpyga2#
这是我使用当前状态得到的最接近的解决方案。
它在大多数情况下都能工作。
但是在带有可选参数的重载中存在几个问题。
xtupzzrd3#
这是另一个用例:
实际:
期望:
cxfofazt4#
希望看到解决这个问题的方法。这是我不喜欢使用标准NodeJS EventEmitter的原因之一。这些事件经常有10多个以上的重载,所有事件名都需要手动输入。当你试图对事件进行编码时,这很好,但目前任何优雅的类型推断都是不可能的。
具体的例子是
events.on
和events.once
,它们是两个通过promise轻松与emitter交互的两级函数,例如:当你使用大量的
async/await
时,这两个函数都很棒,它可以节省在等待某些init/close-event(如net.Server
、listening
和close
)时的恼人的回调嵌套。这会导致一些非常漂亮的线性代码。但是TypeScript无法为你提供任何关于任何emitter上存在的事件的完成帮助,这使得如果不熟悉emitter的话,这两个函数使用起来非常繁琐。
解决这个问题也可能成为与泛型函数相关问题的一个垫脚石,更智能的
ReturnType
和bind(...args)
操作。我希望能最终准确地使用柯里化和泛型。ivqmmu1c5#
这是一个关于重复问题的讨论。根据提供的信息,这个问题与之前的某个问题有关,该问题被关闭为重复问题,但最终被拒绝。对于当前的问题,无法确定其具体情况。
eh57zj3b6#
Cross-linking #17961
bgibtngc7#
从用户的Angular 来看,这个功能非常有用。我希望官方能更多地从用户的Angular 出发。
szqfcxe28#
交叉链接到#52035(评论)以及具体术语“呼叫类型”