TypeScript泛型<T extends unknown[]>与<T>的差异及报错原因
TypeScript自定义call函数的泛型疑问解答
原代码中unknown[]的作用
原代码里的泛型T extends unknown[],是把T约束为元组类型——因为函数的参数列表在TypeScript里会被推断成元组(比如fill的参数(number, string)对应元组类型[number, string])。
用unknown[]作为约束,是因为元组属于数组的子类型,unknown是最宽松的类型约束,能兼容任意类型的参数元组,保证这个call函数可以接收任何参数结构的函数,不会对参数类型做不必要的限制,最大化函数的通用性。
你的写法报错的原因
你改写的代码里,泛型T没有约束为元组,TypeScript会把它推断成单个参数的类型。比如调用call(fill, 10, 'a')时,T会被推断为number | string,对应的args就是(number | string)[]——这是一个元素类型为联合类型的数组,元素顺序和数量都不固定。
但fill函数要求的参数是固定顺序的两个值:第一个是number,第二个是string(对应元组类型[number, string]),和(number | string)[]类型不匹配,所以TypeScript会抛出类型错误。
代码示例对比
原正确代码:
function call<T extends unknown[], R>( f: (...args: T) => R, ...args: T ): R { return f(...args) } function fill(length: number, value: string): string[] { return Array.from({length}, () => value) } call(fill, 10, 'a') // 类型推断正常,返回string[]
你的报错代码:
function call<T, R>( f: (...args: T[]) => R, ...args: T[] ): R { return f(...args) } call(fill, 10, 'a') // 类型不匹配报错:fill需要(number, string),但传入的是(number | string)[]
内容的提问来源于stack exchange,提问作者techoaman
相关产品推荐
相关产品推荐

