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

如何为方法指定类型以返回原始值或传入类的实例?

修复泛型类的返回类型推断问题

我来帮你搞定这个类型推断的问题,你的核心需求是让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(); 

关键修复点说明

  1. PrimitiveFromWrapper类型:精准对应原始包装构造函数到原始值类型,比如NumberConstructor映射为number。
  2. Constructor类型:明确区分原始包装构造函数和普通类构造函数,确保普通类的泛型参数绑定的是实例类型的构造逻辑。
  3. ReturnValue类型:通过条件类型自动分支判断——如果是原始包装构造函数则返回原始值,否则返回类的实例。
  4. getValue方法实现:运行时配合类型判断,对原始包装对象调用valueOf()返回原始值,普通类直接返回实例,同时用类型断言辅助TypeScript完成类型推断。

修改后你的测试场景都能得到符合预期的结果:

  • new Foo(Number).getValue()返回number类型
  • new Foo(Matrix).getValue()返回Matrix实例类型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:58:32