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

如何无需类型断言从构造函数参数推断Resolver.resolve返回类型

解决方案:无需类型断言的类型推断优化

问题核心是原ConstructorMap的递归约束让TypeScript无法精准追踪每个构造函数对应的Model泛型参数,我们可以通过调整Resolver的泛型定义和resolve方法的返回类型来解决:

// 保留原Model、FooModel、BarModel定义不变
abstract class Model<T> {
  public readonly value: T;

  public constructor(value: T) {
    this.value = value;
  }
}

class FooModel extends Model<{ x: number; y: number }> {
  public constructor() {
    super({ x: 1, y: 2 });
  }
}

class BarModel extends Model<{ name: string }> {
  public constructor() {
    super({ name: 'bar' });
  }
}

// 修改Resolver的泛型定义和resolve方法
class Resolver<T extends Record<string, new () => Model<any>>> {
  private readonly constructors: T;

  public constructor(constructors: T) {
    this.constructors = constructors;
  }

  public resolve<K extends keyof T>(key: K): T[K] extends new () => Model<infer U> ? Model<U> : never {
    const constructor = this.constructors[key];
    return new constructor(); // 此处类型自动推断正确,无需断言
  }
}

// 测试代码
const resolver = new Resolver({
  FooModel,
  BarModel,
});

const foo = resolver.resolve('FooModel'); // 类型为Model<{ x: number; y: number }>
console.log(foo.value.x); // 类型提示正常

const bar = resolver.resolve('BarModel'); // 类型为Model<{ name: string }>
console.log(bar.value.name); // 类型提示正常

原理说明

  1. 去掉了原有的ConstructorMap递归约束,直接让Resolver的泛型T继承Record<string, new () => Model<any>>,明确每个属性都是无参构造的Model子类。
  2. 在resolve方法的返回类型中,使用条件类型T[K] extends new () => Model<infer U> ? Model<U> : never,TypeScript会自动根据传入的K(构造函数名称),提取对应构造函数返回的Model实例的泛型参数U,从而精准推断返回值类型。
  3. 此时new constructor()的返回值会被TypeScript正确关联到对应的Model<U>类型,无需额外断言。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 11:24:16