在TypeScript3.1中,我有一个泛型函数,其参数为
(TInput, string)
(string)
取决于泛型的类型参数
TInput extends undefined
. 目前我正在使用新的
generic rest parameters
将函数参数键入为条件元组类型的功能:
function test (
...args: TInput extends undefined ? [string] : [TInput, string]): void
)
这几乎是完美的工作。当我用具体类型实例化泛型函数时,VSCode只显示应用于该泛型类型的重载。耶!
args_0
和
args_1
input
对于泛型参数(如果存在的话)和
name
对于字符串参数。
是否有任何方法可以在不丢失参数计数和类型的(正确的)Intellisense的情况下为这些参数附加更友好的名称?
顺便说一句,只要核心需求工作正常,我可以使用不使用元组的解决方案,也就是说:当泛型函数用实数类型实例化并且我将鼠标悬停在VSCode中的函数上时,我会看到对该具体类型有效的正确参数计数、名称和类型。
我试着添加重载(见下面的注释代码),但不知道如何编译重载。我得到:
在这个示例的早期迭代中,我可以使用类型转换来获取要编译的重载,但这反过来又破坏了参数计数和类型的Intellisense,其中“break”表示(与下面的代码不同)两个重载始终以Intellisense显示,即使泛型类型参数应该将列表缩小为一个有效的超载。
const makeTest = <TInput>() => {
// Adding the overloads below doesn't work as expected. There are two problems:
// 1. compiler error: "Overload signature is not compatible with function implementation. ts(2394)"
// 2. if I use a cast to get around the compile error, both overloads show in Intellisense regardless of TInput
// function test (name: string): void;
// function test (input: TInput, name: string): void;
function test (...args: TInput extends undefined ? [string] : [TInput, string]): void {
// do stuff
}
return test;
}
// type inferred as: const f1: (args_0: string) => void
const f1 = makeTest<undefined>();
// type inferred as: const f2: (args_0: number, args_1: string) => void
const f2 = makeTest<number>();
这是一个
playground link
顺便说一句,我知道我可以通过颠倒参数顺序来简化这个过程,但是改变它面向JS的签名是不实际的。我现在只能更改TS的输入。另外,即使参数是反向的,我也非常喜欢用特定类型实例化泛型将如何移除无效的重载,我不知道这是否适用于传统的可选参数。