能否检测泛型函数类型?如何实现IsGenericFunction泛型类型?
如何在TypeScript中检测泛型函数类型
要实现IsGenericFunction<T>类型来区分泛型函数、非泛型函数和非函数类型,可以利用TypeScript类型系统的特性——泛型函数的原始类型与其任意实例化版本的类型不相等,结合条件类型进行判断。
实现方案
以下是满足需求的IsGenericFunction<T>类型定义:
type IsGenericFunction<T> = // 第一步:过滤非函数类型 T extends (...args: any[]) => any ? ( // 第二步:先排除明确不是泛型函数的情况 (T extends <U>(...args: any[]) => any ? true : false) extends false ? false : // 第三步:通过泛型实例化的差异性判断是否为真正的泛型函数 (<U>() => T extends <U>(...args: any[]) => any ? true : false) extends <U>() => true ? false : true ) : false;
逻辑解释
- 非函数类型过滤:通过
T extends (...args: any[]) => any直接将非函数类型判定为false。 - 初步泛型签名匹配:先检查
T是否能匹配基础泛型函数签名<U>(...args: any[]) => any,如果不能匹配,说明是普通非泛型函数,返回false。 - 泛型差异性校验:
- 对于非泛型函数,它可以匹配任意泛型函数签名,因此
<U>() => T extends <U>(...) => any ? true : false会被TypeScript简化为<U>() => true。 - 对于泛型函数,其类型依赖于泛型参数
U,上述条件无法被简化为固定的<U>() => true,因此通过判断二者是否相等,就能区分出真正的泛型函数。
- 对于非泛型函数,它可以匹配任意泛型函数签名,因此
测试用例
// 测试泛型函数 type TestGeneric1 = IsGenericFunction<<T>(a: T) => T>; // true type TestGeneric2 = IsGenericFunction<<T, U>(a: T, b: U) => unknown>; // true // 测试非泛型函数 type TestNonGeneric = IsGenericFunction<(a: number) => string>; // false // 测试非函数类型 type TestNonFunction = IsGenericFunction<string>; // false type TestNonFunction2 = IsGenericFunction<{ id: number }>; // false
局限性说明
- 该方案基于TypeScript类型系统的隐式简化规则,对于部分带有复杂泛型约束的函数,可能需要调整匹配逻辑,但能覆盖绝大多数常见场景。
- TypeScript本身没有提供直接检测泛型函数的原生类型运算符,这是目前社区常用的间接实现方式。
内容的提问来源于stack exchange,提问作者Glen Whitney
相关产品推荐
相关产品推荐

