В TypeScript 3.1 у меня есть универсальная функция, аргументы которой (TInput, string)
или (string)
, в зависимости от того, является ли параметр типа универсального TInput extends undefined
.В настоящее время я использую новую универсальную функцию остальных параметров для ввода аргументов функции в качестве условного типа кортежей:
function test (
...args: TInput extends undefined ? [string] : [TInput, string]): void
)
Это почти идеально работает.Когда я создаю экземпляр универсальной функции с конкретным типом, VSCode показывает только перегрузку, которая применяется к этому универсальному типу.Yay!
Но есть одна проблема: Intellisense в VSCode сообщает имена параметров как args_0
и args_1
вместо более понятных для человека имен, таких как input
для универсального параметра (если он есть) и name
для строкового параметра.
Есть ли способ присоединить более дружественные имена к этим параметрам, не теряя (правильный) Intellisense для количества параметров и типа (ов)?
КстатиХорошо с решением, которое не использует кортежи, пока основные требования работают хорошо, а именно: когда генерируется универсальная функция с реальным типом, и я наводю указатель мыши на функцию в VSCode, я вижу правильный счетчик параметров, имя(s) и тип (ы), которые действительны для этого конкретного типа.
Я попытался добавить перегрузки (см. Прокомментированный код ниже), но не мог понять, как заставить перегрузки компилироваться.Я получил: Сигнатура перегрузки не совместима с реализацией функции.ts (2394)
В более ранней итерации этого примера я мог использовать приведение типов для получения перегрузок при компиляции, но это в свою очередь нарушало Intellisense для числа параметров и типов, где "сломался""означает, что (в отличие от приведенного ниже кода) в 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>();
Вот ссылка детская площадка для этого кода, чтобы вы могли увидеть проблему вживую.
Кстати, я знаю, что мог бы упростить это, изменив порядок параметров, но изменить его сигнатуру на JS непрактично.Я только могу изменить типизацию TS в этой точке.Кроме того, даже если параметры были изменены на противоположные, мне действительно нравится, как создание экземпляра универсального с определенным типом удалит недопустимую перегрузку, и я не знаю, будет ли это работать с традиционными необязательными параметрами.