Лично я не вижу ничего плохого в вашем "многословном" звонке
const z = apiResponse.then(_ => mapData<number>(_));
но если вы хотите что-то еще, читайте дальше:
Универсальные типы функций, в которых одна функция может действовать как функция нескольких типов, позволяют указывать параметр универсального типа только при его вызове. Ваша функция mapData
имеет следующий тип:
type GenFunc = <T>(res: { data: T; }) => T
const verifyMapData: GenFunc = mapData; // okay
Обратите внимание, что GenFunc
не является псевдонимом универсального типа; это псевдоним определенного типа, который относится к общему функциональному типу. Вы можете думать о параметре типа T
как о «принадлежащем» сигнатуре вызова, а не имени функции или имени любого псевдонима типа функции. Поскольку оно не принадлежит имени функции, вы не можете написать mapData<T>
отдельно, а поскольку оно не принадлежит имени типа GenFunc
, вы также не можете написать GenFunc<T>
.
Сравните это с другим, но связанным псевдонимом универсального типа, который относится к семейству конкретных типов функций:
type GenAlias<T> = (res: {data: T; }) => T
В этом типе параметр универсального типа «принадлежит» имени псевдонима типа, а не типу функции, который он представляет.
Теперь, к сожалению, верно то, что системе типов TypeScript в настоящее время не хватает выразительности, необходимой для того, чтобы взять тип GenFunc
и автоматически сгенерировать тип GenAlias<T>
. По крайней мере, сейчас вам нужно вручную написать определение типа GenAlias<T>
, как я только что сделал.
Что компилятор может сделать, так это распознать, что значение типа GenFunc
можно присвоить переменной типа GenAlias<T>
для любого конкретного T
, которое вы хотите, поэтому следующее компилируется просто отлично:
const mapDataNumber: GenAlias<number> = mapData; // okay
И поэтому вы можете получить следующее для компиляции без дополнительного вызова функции, если это имеет значение:
const w = apiResponse.then(mapDataNumber); // Promise<number>
Кроме того, если вы не хотите тратить строку на присвоение переменной, вы можете использовать утверждение типа для немного меньшей безопасности типов, но абсолютно без эффекта времени выполнения:
const v = apiResponse.then(mapData as GenAlias<number>); // Promise<number>
Любой из них должен работать на вас.
Хорошо, надеюсь, это поможет. Удачи!
Link to code
person
jcalz
schedule
11.12.2019
_ => f<T>(_)
, вероятно, лучшее, на что вы можете здесь надеяться. - person jcalz   schedule 11.12.2019