Чтобы выполнить sh, мы бы использовали обобщенное ограничение типа c.
На самом деле это то, как параметры типа языка предоставляют вспомогательные типы Parameters<T>
и ReturnType<T >
. и что в свою очередь вызывает ошибку.
Чтобы создать экземпляр обобщенного типа c, скажем ReturnType<T>
, с нашим параметром типа, наш параметр типа должен быть ограничен по крайней мере так же ограничительно, как параметр типа ReturnType
. Глядя на определение ReturnType<T>
, мы можем определить минимальные ограничения, которые нам нужно применить, и связанный с ними синтаксис
type ReturnType<T extends (...args: any) => any> =
// details
Не беспокойтесь о реализации (после =
), поскольку это более широкий топи c. В этой ситуации мы сосредоточимся на ограничениях T
, определенных с использованием ключевого слова extends
при объявлении T
.
Следовательно, чтобы передать T declared
на BoundThunk<T>
в ReturnType<T>
мы должны ограничить его, чтобы он отвечал вышеуказанным требованиям (обратите внимание, что Parameters<T>
имеет идентичные ограничения).
type BoundThunk<T extends (...args: any) => any> =
(...args: Parameters<T>) => ReturnType<ReturnType<T>>;
Однако наши требования к T
на самом деле больше ограничительны, поскольку мы применяем ReturnType
дважды, ReturnType<ReturnType<T>>
, подразумевая, что T
является функцией более высокого порядка, в этом случае функция, которая возвращает функцию.
Поэтому мы уточним наше ограничение соответственно
type BoundThunk<T extends (...args: any) => (...args: any) => any> =
(...args: Parameters<T>) => ReturnType<ReturnType<T>>;