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

如何从类自身方法的返回值推断类泛型参数

解决TypeScript泛型Controller的类型推断问题

核心问题分析

原代码中类级别的泛型参数Body无法与getBody方法的返回值建立关联,导致返回具体对象时触发类型不匹配错误。我们需要让TypeScript从getBody的返回值自动推断出Body类型,同时保留main方法的参数自动补全能力。

解决方案:绑定泛型与抽象方法返回值

通过让子类实现getBody时的返回值决定父类的泛型参数,无需手动指定泛型即可完成实例化,同时保证类型安全。

优化后的抽象类代码

abstract class Controller<Body extends Record<string, any>> {
  // 抽象方法,子类需返回具体Body类型
  abstract getBody(): Body;

  // main方法参数类型与getBody返回值自动对齐,获得补全
  main(body: Body) {
    console.log(body);
  }
}

正确实现子类的两种方式

方式1:自动推断泛型(无需手动指定)

在子类中明确getBody的返回类型,TypeScript会自动将该类型作为父类的Body泛型:

class MyController extends Controller {
  getBody(): { a: string } {
    return { a: 'b' }; // 类型匹配,无错误
  }
}

const ctrl = new MyController();
// main方法自动补全参数,仅接受{ a: string }类型
ctrl.main({ a: 'test' }); // 合法
ctrl.main({ b: 'test' }); // 类型错误

方式2:手动关联Zod Schema(原需求实际场景)

如果使用Zod做参数校验,可通过z.infer提取Schema对应的TS类型,绑定到泛型:

import { z } from 'zod';

// 定义Zod校验规则
const BodySchema = z.object({
  a: z.string()
});
// 提取Schema对应的TS类型
type BodyType = z.infer<typeof BodySchema>;

abstract class Controller<Body extends Record<string, any>> {
  abstract getBody(): Body;
  abstract schema: z.ZodSchema<Body>;

  main(body: Body) {
    this.schema.parse(body); // 自动校验参数
    console.log(body);
  }
}

class MyController extends Controller<BodyType> {
  schema = BodySchema;

  getBody() {
    return { a: 'b' }; // 符合BodyType类型
  }
}

const ctrl = new MyController();
ctrl.main({ a: 'hello' }); // 参数自动补全,校验通过

关键总结

  • 让子类getBody的返回值类型主导父类泛型Body的推断,而非反向约束。
  • 无需手动指定泛型时,明确子类getBody的返回类型即可触发自动推断。
  • 结合Zod时,通过z.infer实现Schema与TS类型的双向绑定,兼顾校验与类型提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:05:04