如何改写TypeScript数组类型谓词函数,兼顾泛型指定与参数推断?
解决TypeScript数组类型断言函数的双向兼容问题
你可以通过双重泛型参数+默认值的方式改写函数,同时支持显式指定数组类型和自动参数推断:
type MyTypePredicate<T> = (value: any) => value is T // 双重泛型:A是目标数组类型,T是元素类型(默认从A提取) function createTypePredicateForArray<A extends T[], T = A[number]>(item: T): MyTypePredicate<A> { // 替换为你的实际验证逻辑,示例仅做基础数组检查 return ((value: any) => { if (!Array.isArray(value)) return false; return value.every(v => typeof v === typeof item); }) as MyTypePredicate<A>; }
验证两种调用方式:
- 显式指定数组类型:
const a1 = createTypePredicateForArray<number[]>(42); // a1 类型为 MyTypePredicate<number[]>,符合预期
- 自动参数推断:
const a2 = createTypePredicateForArray(42); // a2 类型为 MyTypePredicate<number[]>,符合预期
原理说明:
- 泛型
A约束为T[],确保它是一个数组类型,与你要求的返回值MyTypePredicate<A>类型保持一致; - 泛型
T设置默认值A[number],当显式指定A时,T会自动提取A的元素类型,匹配传入的item参数; - 当不指定
A时,TypeScript会先从item推断出T,再根据A extends T[]的约束,自动推断A为T[],解决了原函数的推断失效问题。
原函数推断失效的原因:
原函数仅用单个泛型A extends any[],当不指定A时,TypeScript需要从item: A[number]反向推导A,但A可以是任意包含该元素类型的数组(比如number[]、readonly number[]、[number, number]等),TypeScript无法确定具体类型,只能 fallback 到any[]。
内容的提问来源于stack exchange,提问作者Tvartom
相关产品推荐
相关产品推荐

