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

TypeScript中如何正确提取泛型函数的参数类型并复用?

解决TypeScript泛型函数参数类型提取问题

你遇到的问题是,直接提取泛型函数的参数类型时,得到的结果不是可复用的泛型类型,而是绑定了未确定类型变量的具体类型,因此无法用FnProps<T>的方式调用。

正确方案:让类型工具支持泛型参数传递

我们可以调整GetProps的定义,让它同时接受原函数类型和泛型参数T,从而动态生成对应T的参数类型:

interface Props<T> {
    data: T[];
    test: (x: T) => void
}

function fn<T>(props: Props<T>): void {
    return;
};

// 调整后的GetProps:第一个参数是原函数类型,第二个是泛型参数T
type GetProps<Func, T> = Func extends <U>(props: infer Param) => void 
  ? Param extends Props<U> 
    ? Props<T> 
    : never 
  : never;

// 定义fn2,使用GetProps传入typeof fn和泛型T
function fn2<T>(props: GetProps<typeof fn, T>): void {
    return;
}

// 测试验证:类型推导正常工作
fn2({
    data: [1, 2, 3],
    test: (x) => console.log(x.toFixed(2)) // x自动推导为number
});

fn2({
    data: ["foo", "bar"],
    test: (x) => console.log(x.length) // x自动推导为string
});

更通用的写法(不依赖Props接口)

如果不想直接依赖Props的结构,可以完全从函数类型中提取泛型参数的约束:

interface Props<T> {
    data: T[];
    test: (x: T) => void
}

function fn<T>(props: Props<T>): void {
    return;
};

// 完全从函数类型提取泛型参数的结构
type ExtractGenericParam<Func> = 
  Func extends <T>(props: infer Param) => void 
    ? <U>() => Param extends { data: T[], test: (x: T) => void } 
      ? { data: U[], test: (x: U) => void } 
      : never 
    : never;

type FnProps = ExtractGenericParam<typeof fn>;

function fn2<T>(props: ReturnType<FnProps<T>>): void {
    return;
}

这两种写法都能让fn2和原函数fn保持完全等价的类型约束和推导能力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 09:35:22