Я изучаю общие принципы машинописного текста, в частности Выражения создания экземпляров.
Интересно, почему машинописный скрипт не позволяет частично указывать аргументы типа в универсальной функции, чтобы создать новую универсальную функцию с меньшим количеством переменных типа (новая универсальная функция менее гибкая и допускает повторное использование с точки зрения типа, чем старая).
Например:
type TypeA = { a: string }; // line (1)
function mergeFunc<T_1, T_2>(a: T_1, b: T_2) { // line (2)
return { ...a, ...b }; // line (3)
}
let newGenMergeFunc = mergeFunc<TypeA, Tp>; // line (4)
В этом примере у меня есть одно определение типа (typeA
) и функция mergeFunc
, которые содержат две переменные типа (T_1
и T_2
). Типовая подпись mergeFunc
:
mergeFunc<T_1, T_2>(a: T_1, b: T_2): T_1 & T_2
Я хочу создать более конкретную версию mergeFunc
, используя выражение экземпляра. Я создал новую функцию (newGenMergeFunc
), передав фактический тип TypeA
первому параметру типа (T_1
) и сохранив второй параметр типа как переменную типа (Tp
).
Когда я запускаю приведенный выше пример, я ожидаю, что: newGenMergeFunc
станет универсальной функцией с одной переменной типа (Tp
) и ее сигнатурой:
newGenMergeFunc<Tp>(a: TypeA, b: Tp): TypeA & T_2
. При этом TypeA
— это фактический тип, а Tp
— параметр типа (заполнитель типа или переменная типа). Однако компилятор Typescript не позволяет мне этого сделать.
Не могли бы вы указать причину? Спасибо за внимание к моему глупому вопросу.
Можно, но использованный вами синтаксис неверен.
let newGenMergeFunc:<Tp> (a: TypeA, b: Tp) => TypeA & Tp = mergeFunc;
Чтобы Tp
был действительным, вам нужен контекст, в котором mergeFunc<TypeA, Tp>
уже является параметром типа, например.
function makeMergeFunc<Tp>(){ return mergeFunc<TypeA, Tp>; }
let unknownMergeFunc = makeMergeFunc();
спасибо @Caleth, твой ответ меня так заинтересовал. Но в своем ответе let newGenMergeFunc:<Tp> (a: TypeA, b: Tp) => TypeA & Tp = mergeFunc;
используйте Контекстную типизацию и не используйте Выражения создания экземпляров.
@LeoPkm2-1 см. редактирование. Вам нужно место для Tp
, которое будет представлено как параметр типа.
Большое спасибо, внимательно обдумав ваш ответ, я понял. Извините за такой поздний ответ. Моя искренняя благодарность
Причина в том, что это недостающая функция. TS не позволяет пропускать обобщенные функции при вызове универсальной функции согласно ms/TS#10571, а также нет соответствующего способа сделать это с выражением создания экземпляра. Если вы хотите такого поведения, вам придется написать тип вручную, как показано в ответе Калета ниже.