Они сильно различаются в сигнатуре функции, которую они определяют.
- Первый определяет сигнатуру обычной функции, которую можно настроить с помощью параметра типа при использовании, и этот тип становится фиксированным в сигнатуре
- Второй определяет сигнатуру общей функции, то есть функцию, которая может принимать параметр любого типа
T
, причем T
выводится (или указывается явно) при вызове функции.
Рассмотрим следующие объявления:
declare const fn: FnWithRequiredParam<number>
declare const genericFn: FnWithParamInferred;
// T was fixed on declaration
fn(1) // ok
fn("1") // err
// T is decded by the caller
genericFn(1) // ok T is number for this call
genericFn("1") // ok T is string for this call
genericFn<number>("1") // err T was specified as number but string was passed in
Причиной ошибки, которую вы получаете, является то, что вы пытаетесь присвоить функцию с параметром number
функции, которая должна принимать параметр любого типа T
, причем T
определяется решением вызывающая функция. Только универсальная функция может удовлетворить тип FnWithParamInferred
var f: FnWithParamInferred = <T>(a: T) => { console.log(a) }
Я думаю, что вы действительно хотите, чтобы иметь возможность пропустить явный аргумент типа из объявления переменной и сделать его вывод основанным на присвоенном ему значении. Typescript не поддерживает это. Если вы определите аннотацию типа для переменной, то для нее не будет никакого вывода.
Вы можете вообще пропустить аннотацию типа, чтобы компилятор мог определить тип функции:
var f = (a: number) => { console.log(a) } // inferred as (a: number) => void
Или вы можете определить универсальную вспомогательную функцию для вывода T
, но ограничить сигнатуру функции на основе FnWithRequiredParam
function createFunction<T>(fn: FnWithRequiredParam<T>) {
return fn;
}
var f = createFunction((a: number) => { console.log(a) }) // inferred as FnWithRequiredParam<number>