См. Следующий фрагмент
declare function foo<T>(a: T): (b: T) => boolean;
foo(111)(222); // T inferred as 'number'
foo('hello')('bye'); // T inferred as 'string'
declare function bar<T extends number | string>(a: T): (b: T) => boolean;
bar(111)(222); // T inferred as '111'
bar('hello')('bye'); // T inferred as 'hello'
площадка
Как вы можете видеть, функция bar
выводит тип T
в качестве литерального типа ('111'
и 'hello'
в примере), но в функции foo
они выводятся как number
или string
, и единственным отличием является ограничение.
Любопытно, если использовать коробочные типы следующим образом
declare function baz<T extends Number | String>(a: T): (b: T) => boolean;
затем T
выводится как number
и string
, но достаточно, чтобы один из них был примитивным типом, а T
выводится как литеральный тип:
declare function brr<T extends Number | string>(a: T): (b: T) => boolean;
Итак, вопрос: Почему foo('hello')
выводит T
как string
, но bar('hello')
выводит T
как 'hello'
? Почему это происходит только тогда, когда T
ограничено (по крайней мере, в этом примере)?