当 args 是条件元组类型时重载参数的 Intellisense 命名
Intellisense naming of overload parameters when args are a conditional tuple type
在 TypeScript 3.1 中,我有一个泛型函数,其参数是 (TInput, string)
或 (string)
,具体取决于泛型的类型参数是否为 TInput extends undefined
。目前,我正在使用新的 generic rest parameters 功能将函数的参数键入为条件类型的元组:
function test (
...args: TInput extends undefined ? [string] : [TInput, string]): void
)
这几乎完美无缺。当我用具体类型实例化泛型函数时,VSCode 只显示适用于该泛型类型的重载。耶!
但存在一个问题:VSCode 中的 Intellisense 将参数名称报告为 args_0
和 args_1
,而不是通用参数的更易读的名称,如 input
(如果它在那里)和 name
作为字符串参数。
有没有什么方法可以在不丢失参数计数和类型的(正确的)Intellisense 的情况下将更友好的名称附加到这些参数?
顺便说一句,我可以接受不使用元组的解决方案,只要核心要求工作正常,即:当用真实类型实例化泛型函数时,我将鼠标悬停在 VSCode,我看到了对该具体类型有效的正确参数计数、名称和类型。
我尝试添加重载(请参阅下面的注释代码)但无法弄清楚如何让重载进行编译。我得到:重载签名与函数实现不兼容。 ts(2394)
在此示例的早期迭代中,我能够使用类型转换来获得要编译的重载,但这反过来破坏了参数计数和类型的 Intellisense,其中 "broke" 表示(与下面的代码)两个重载始终显示在 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 类型。此外,即使参数被颠倒,我也非常喜欢用特定类型实例化泛型将消除无效的重载,我不知道这是否适用于传统的可选参数。
我只想将函数断言为依赖于 TInput
的条件类型,这将为您提供您想要的更好的智能感知。您无法在剩余参数中轻松指定元组的参数名称:
const makeTest = <TInput>() => {
function test (...args: [string] | [TInput, string]): void {
// do stuff
}
return test as (TInput extends undefined ? ((name:string) => void) : ((input: TInput, name: string) => void);
}
或具有实现和 public 签名的版本 makeTest
:
function makeTest<TInput>(): (TInput extends undefined ? ((name: string) => void) : ((input: TInput, name: string) => void))
function makeTest<TInput>(): ((name: string) => void) | ((input: TInput, name: string) => void) {
function test(...args: [string] | [TInput, string]): void {
// do stuff
}
return test;
}
在 TypeScript 3.1 中,我有一个泛型函数,其参数是 (TInput, string)
或 (string)
,具体取决于泛型的类型参数是否为 TInput extends undefined
。目前,我正在使用新的 generic rest parameters 功能将函数的参数键入为条件类型的元组:
function test (
...args: TInput extends undefined ? [string] : [TInput, string]): void
)
这几乎完美无缺。当我用具体类型实例化泛型函数时,VSCode 只显示适用于该泛型类型的重载。耶!
但存在一个问题:VSCode 中的 Intellisense 将参数名称报告为 args_0
和 args_1
,而不是通用参数的更易读的名称,如 input
(如果它在那里)和 name
作为字符串参数。
有没有什么方法可以在不丢失参数计数和类型的(正确的)Intellisense 的情况下将更友好的名称附加到这些参数?
顺便说一句,我可以接受不使用元组的解决方案,只要核心要求工作正常,即:当用真实类型实例化泛型函数时,我将鼠标悬停在 VSCode,我看到了对该具体类型有效的正确参数计数、名称和类型。
我尝试添加重载(请参阅下面的注释代码)但无法弄清楚如何让重载进行编译。我得到:重载签名与函数实现不兼容。 ts(2394)
在此示例的早期迭代中,我能够使用类型转换来获得要编译的重载,但这反过来破坏了参数计数和类型的 Intellisense,其中 "broke" 表示(与下面的代码)两个重载始终显示在 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 类型。此外,即使参数被颠倒,我也非常喜欢用特定类型实例化泛型将消除无效的重载,我不知道这是否适用于传统的可选参数。
我只想将函数断言为依赖于 TInput
的条件类型,这将为您提供您想要的更好的智能感知。您无法在剩余参数中轻松指定元组的参数名称:
const makeTest = <TInput>() => {
function test (...args: [string] | [TInput, string]): void {
// do stuff
}
return test as (TInput extends undefined ? ((name:string) => void) : ((input: TInput, name: string) => void);
}
或具有实现和 public 签名的版本 makeTest
:
function makeTest<TInput>(): (TInput extends undefined ? ((name: string) => void) : ((input: TInput, name: string) => void))
function makeTest<TInput>(): ((name: string) => void) | ((input: TInput, name: string) => void) {
function test(...args: [string] | [TInput, string]): void {
// do stuff
}
return test;
}