TypeScript:如何在泛型约束中自动推断泛型类型?
TypeScript泛型接口中复用嵌套泛型类型的实现方案
场景与问题
我定义了一个泛型接口IPoint,用来表示包含x、y坐标的点:
export interface IPoint<TX, TY> { x: TX; y: TY; }
接下来想定义ISeries接口,要求它的泛型参数TPoint必须继承IPoint,但直接写下面的代码会报错——因为IPoint必须指定TX和TY类型参数:
export interface ISeries<TPoint extends IPoint> { points: Array<TPoint>; }
我尝试过用infer来自动推断TX和TY,但这种写法不生效:
export interface ISeries<TPoint extends IPoint<infer TX, infer TY>> { points: Array<TPoint>; }
之前找到的可行方案是给ISeries额外添加TX和TY作为泛型参数,但每次使用都要指定三个类型,非常繁琐;如果直接用IPoint<any, any>做约束,又会丢失x和y的真实类型信息。
补充需求
我需要在ISeries中添加transformYValues方法,让它的参数yValue能获得强类型约束,对应TPoint中y的类型:
export interface ISeries<TPoint extends IPoint<infer TX, infer TY>> { points: Array<TPoint>; transformYValues?: (yValue: TY) => number; }
最终解决方案
借助TypeScript的索引访问类型可以完美解决这个问题,代码如下:
export interface ISeries<TPoint extends IPoint<any, any>> { points: Array<TPoint>; transformYValues?: (yValue: TPoint['y']) => number; }
核心逻辑是:
- 用
IPoint<any, any>作为TPoint的泛型约束,满足语法要求的同时不限制具体类型 - 通过
TPoint['y']索引访问类型,直接获取TPoint中y属性的真实类型,为transformYValues的参数提供强类型约束
这样既不用额外添加多余的泛型参数,又能完整保留类型信息,实现简洁且类型安全的代码。
内容的提问来源于stack exchange,提问作者Marc F
相关产品推荐
相关产品推荐

