...args 的通用类型?
generic type for ...args?
我有一个函数time
const time = <T>(fn: (...args: any[]) => Promise<T>, ...args: any[]): Promise<T> => {
return new Promise(async (resolve, reject) => {
const timer = setTimeout(() => reject(`Error: ${fn.name} timed out`), ms)
try {
resolve(await fn.bind(thisArg)(...args))
} catch(err) {
reject(err)
} finally {
clearTimeout(timer)
}
})
}
我想知道是否有办法避免使用 any
作为 ...args
的类型?特别是因为我想将 fn
签名 (fn: (...args: any[]) => Promise<T>
) 中 ...args
的类型与 ...args
的类型(time
函数的第二个参数).这两个 ...args
是相同的参数,因此它们似乎应该通过泛型关联起来。我想到了这样的事情:
const time = <T, U>(fn: (...args: U[]) => Promise<T>, ...args: U[]): Promise<T>
但这似乎是错误的,因为参数不会都是同一类型。相反,无论 fn
签名中 ...args
的类型是什么,也将是 time
函数的第二个参数 ...args
的类型。
我们可以这样做:
const time = <T, U extends unknown[]>(fn: (...args: U) => Promise<T>, ...args: U): Promise<T>
the arguments will not all be of the same type
...args
的类型确实必须是 array/tuple,因为它使用了剩余运算符。
但不是键入 U[]
,这确实强制每个单独的参数都是类型 U
,我们可以简单地使用泛型键入整个数组,前提是它被限制为一个数组:U extends unknown[]
现在我们可以做 ...args: U
我有一个函数time
const time = <T>(fn: (...args: any[]) => Promise<T>, ...args: any[]): Promise<T> => {
return new Promise(async (resolve, reject) => {
const timer = setTimeout(() => reject(`Error: ${fn.name} timed out`), ms)
try {
resolve(await fn.bind(thisArg)(...args))
} catch(err) {
reject(err)
} finally {
clearTimeout(timer)
}
})
}
我想知道是否有办法避免使用 any
作为 ...args
的类型?特别是因为我想将 fn
签名 (fn: (...args: any[]) => Promise<T>
) 中 ...args
的类型与 ...args
的类型(time
函数的第二个参数).这两个 ...args
是相同的参数,因此它们似乎应该通过泛型关联起来。我想到了这样的事情:
const time = <T, U>(fn: (...args: U[]) => Promise<T>, ...args: U[]): Promise<T>
但这似乎是错误的,因为参数不会都是同一类型。相反,无论 fn
签名中 ...args
的类型是什么,也将是 time
函数的第二个参数 ...args
的类型。
我们可以这样做:
const time = <T, U extends unknown[]>(fn: (...args: U) => Promise<T>, ...args: U): Promise<T>
the arguments will not all be of the same type
...args
的类型确实必须是 array/tuple,因为它使用了剩余运算符。
但不是键入 U[]
,这确实强制每个单独的参数都是类型 U
,我们可以简单地使用泛型键入整个数组,前提是它被限制为一个数组:U extends unknown[]
现在我们可以做 ...args: U