Почему машинописный текст не позволяет частично указывать аргументы типа, чтобы создать новую универсальную функцию из другой универсальной функции?

Я изучаю общие принципы машинописного текста, в частности Выражения создания экземпляров.

Интересно, почему машинописный скрипт не позволяет частично указывать аргументы типа в универсальной функции, чтобы создать новую универсальную функцию с меньшим количеством переменных типа (новая универсальная функция менее гибкая и допускает повторное использование с точки зрения типа, чем старая).

Например:

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 не позволяет мне этого сделать.

Не могли бы вы указать причину? Спасибо за внимание к моему глупому вопросу.


52
1

Ответ:

Решено

Можно, но использованный вами синтаксис неверен.

let newGenMergeFunc:<Tp> (a: TypeA, b: Tp) => TypeA & Tp = mergeFunc;

Чтобы Tp был действительным, вам нужен контекст, в котором mergeFunc<TypeA, Tp> уже является параметром типа, например.

function makeMergeFunc<Tp>(){ return mergeFunc<TypeA, Tp>; }
let unknownMergeFunc = makeMergeFunc();

Ссылка на игровую площадку