Прежде всего, параметр типа generi c, который вы передаете в Promise
, является типом, который он предоставит при разрешении.
Простой пример:
function numberInThreeSeconds(): Promise<number> {
return new Promise(resolve => {
setTimeout(() => resolve(123), 3000)
// ^ generic paramter type passed to Promise
})
}
Итак, учитывая, что ...
«Я понимаю, что универсальные типы параметризуют типы, такие как функции, параметризуют значение, но почему здесь нам вообще нужно параметризовать типы?»
Вы делаете это так, чтобы разрешенное значение resolveOrTimeout
имело известный тип.
resolveOrTimeout(numberInThreeSeconds(), 5000)
.then(val => console.log(val * 2)) // val is known to be of type number
Поскольку известно, что numberInThreeSeconds
разрешается в number
, тогда использование дженериков позволяет функции возвращать обещание, которое разрешается к тому же типу, что и ее первый аргумент.
«А также, почему даже при вызове функции не предоставляются переменные типа как T в универсальных шаблонах, компилятор не сообщает об ошибках?»
Потому что Функции generi c могут вывести свои общие c параметры на основе использования. В самом простом случае:
function identity<T>(arg: T): T { return arg }
const a = identity('abc') // string
const b = identity(123) // number
Поскольку машинописный текст знает тип аргумента, он может вывести T
, каков бы ни был этот тип, а затем он возвращает тот же тип T
.
То же самое происходит с resolveOrTimeout<T>
.
function resolveOrTimeout<T>(promise: Promise<T>, timeout: number): Promise<T> {}
Аргумент promise: Promise<T>
сообщает машинописному тексту, что он может вывести T
, требуя, чтобы аргумент был обещанием, а затем заглядывал внутрь этого обещания. чтобы найти его разрешенный тип.
И теперь он также может возвращать Promise<T>
, что говорит о том, что эта функция возвращает обещание, которое разрешается к тому же типу, что и аргумент promise
.
Дополнительные сведения о том, как работают обобщенные и обобщенные типы, здесь