You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将泛型类型作为泛型参数传递?TypeScript类型编程疑问

TypeScript实现类型层面的高阶函数方案

你尝试在TypeScript中实现类型层面的高阶函数,但直接传递泛型类型别名时出现报错。以下是问题重现与解决方案:

问题重现

你可运行的代码示例:

type isArrStr<T extends readonly string[]> = T extends readonly["str"] ? true :false ;
type _retAny<T> = any 

type wrapper<T>  = any extends _retAny<isArrStr<infer I>>  ? T extends I ? isArrStr<T> : never :never

// 测试正常
let myVar:wrapper<readonly["str"]> // 返回true
let myVar_1:wrapper<readonly["ll"]> // 返回false
let myVar_2:wrapper<string> // 返回never

但尝试将泛型类型作为参数传递时,出现两个错误:

  • Type 'F' is not generic:TypeScript不允许直接将泛型类型别名作为泛型参数,需先约束F的类型为泛型构造器
  • Generic type 'isArrStr' requires 1 type argument:泛型类型必须传入类型参数才能作为具体类型使用,直接传递泛型类型本身会报错
// 报错代码
type wrapper<F,T>  = any extends _retAny<F<infer I>>  ? T extends I ? F<T> : never :never // 错误:Type 'F' is not generic
let myVar:wrapper<isArrStr,readonly["str"]> // 错误:Generic type 'isArrStr' requires 1 type argument

解决方案

要实现类型层面的高阶函数,需将泛型类型包装为泛型函数类型,并在高阶类型中约束F为接受单个类型参数的泛型函数,通过条件类型推断参数约束与返回类型,最终判断目标类型是否符合要求。

完整实现代码

// 原泛型类型:判断数组是否为readonly["str"]
type isArrStr<T extends readonly string[]> = T extends readonly ["str"] ? true : false;

// 高阶类型:接受泛型函数类型F与待检查类型T
type wrapper<F extends <U>(arg: U) => any, T> = 
  // 推断F的参数约束I和返回类型Result
  F extends <U extends infer I>(arg: U) => infer Result 
    ? // 检查T是否符合F的参数约束
      T extends I 
        ? // 提取T对应的返回结果
          Result extends (U extends T ? infer R : never) 
            ? R 
            : never
        : never
    : never;

// 将原泛型类型包装为泛型函数类型
type IsArrStrFn = <U extends readonly string[]>(arg: U) => isArrStr<U>;

// 测试验证
let myVar: wrapper<IsArrStrFn, readonly ["str"]>; // 类型为true
let myVar_1: wrapper<IsArrStrFn, readonly ["ll"]>; // 类型为false
let myVar_2: wrapper<IsArrStrFn, string>; // 类型为never

简洁写法(利用工具类型)

type isArrStr<T extends readonly string[]> = T extends readonly ["str"] ? true : false;

type wrapper<F extends <U>(arg: U) => any, T> = 
  T extends Parameters<F>[0] 
    ? ReturnType<(F extends <U>() => infer R ? (() => R) : never)> extends (x: T) => infer Res 
      ? Res 
      : never
    : never;

type IsArrStrFn = <U extends readonly string[]>(arg: U) => isArrStr<U>;

// 测试结果一致
let myVar: wrapper<IsArrStrFn, readonly ["str"]>; // true
let myVar_1: wrapper<IsArrStrFn, readonly ["ll"]>; // false
let myVar_2: wrapper<IsArrStrFn, string>; // never

原理说明

  • 泛型函数包装:将原泛型类型isArrStr包装为泛型函数类型IsArrStrFn,使其成为可接受类型参数的"类型构造器"
  • 类型推断:在wrapper中通过条件类型F extends <U extends infer I>(arg: U) => infer Result,推断出泛型函数的参数约束I和返回类型Result
  • 约束检查:判断目标类型T是否符合参数约束I,符合则返回对应类型结果,否则返回never

内容的提问来源于stack exchange,提问作者issueWebpack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:24:55