如何为方法指定类型以返回原始值或传入类的实例?
修复泛型类的返回类型推断问题
我来帮你搞定这个类型推断的问题,你的核心需求是让Foo类的getValue方法根据传入的构造函数自动返回正确的类型:原始包装类返回对应原始值,普通类返回类的实例。咱们一步步来修复:
问题根源分析
你当前的类型定义存在两个核心偏差:
ctor类型把构造函数的返回值统一绑定为T & { valueOf(): returnPrimitive<T> },但对于普通类(比如Matrix),泛型T被推断成了typeof Matrix(构造函数类型)而非Matrix实例类型,导致返回类型错误。returnPrimitive的判断逻辑没有区分构造函数类型和实例类型,无法精准映射原始包装类的返回值。
修复方案
我们重新设计类型体系,让泛型能自动区分原始包装构造函数和普通类构造函数,并推断出正确的返回值:
/* eslint-disable @typescript-eslint/ban-types */ // 映射原始包装构造函数到对应的原始值类型 type PrimitiveFromWrapper<T> = T extends NumberConstructor ? number : T extends StringConstructor ? string : T extends BooleanConstructor ? boolean : never; // 区分两种构造函数:原始包装构造函数、普通类构造函数 type Constructor<T> = // 匹配原始包装构造函数(Number/String/Boolean) T extends NumberConstructor | StringConstructor | BooleanConstructor ? T : // 普通类构造函数,绑定实例类型 { new(...args: any[]): T }; // 自动推断最终返回值类型 type ReturnValue<C> = C extends NumberConstructor | StringConstructor | BooleanConstructor ? PrimitiveFromWrapper<C> : C extends { new(...args: any[]): infer Instance } ? Instance : never; /* eslint-enable */ class Foo<C> { private Type: Constructor<C>; constructor(Type: Constructor<C>) { this.Type = Type; } getValue(val?: any): ReturnValue<C> { const instance = new this.Type(val); // 运行时判断:原始包装对象调用valueOf返回原始值,普通类直接返回实例 if (instance instanceof Number || instance instanceof String || instance instanceof Boolean) { return instance.valueOf() as ReturnValue<C>; } return instance as ReturnValue<C>; } } // 测试验证 class Matrix {} // 正确推断为 number 类型 const numVal = new Foo(Number).getValue('123'); // 正确推断为 Matrix 实例类型 const matrixVal = new Foo(Matrix).getValue();
关键修复点说明
PrimitiveFromWrapper类型:精准对应原始包装构造函数到原始值类型,比如NumberConstructor映射为number。Constructor类型:明确区分原始包装构造函数和普通类构造函数,确保普通类的泛型参数绑定的是实例类型的构造逻辑。ReturnValue类型:通过条件类型自动分支判断——如果是原始包装构造函数则返回原始值,否则返回类的实例。getValue方法实现:运行时配合类型判断,对原始包装对象调用valueOf()返回原始值,普通类直接返回实例,同时用类型断言辅助TypeScript完成类型推断。
修改后你的测试场景都能得到符合预期的结果:
new Foo(Number).getValue()返回number类型new Foo(Matrix).getValue()返回Matrix实例类型
内容的提问来源于stack exchange,提问作者Fuzzyma
相关产品推荐
相关产品推荐

