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
相关产品推荐
相关产品推荐

