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

如何通过类属性自动推导泛型,简化Express自定义Controller的继承写法

这种实现方式完全可行,我们可以通过给基类泛型设置默认值,配合TypeScript的实例类型推断能力实现你要的效果,不需要每次继承时手动传入泛型参数。

具体实现方案

1. 修改Controller基类

给泛型参数设置默认值,同时放宽querySchema的初始类型限制,让子类可以自行收窄类型:

import { Request, Response } from 'express';
import { transvalidate } from './schema/transform-validate';
import { ClassConstructor } from 'class-transformer';

// 给泛型加默认值,子类继承时可省略传参
export abstract class Controller<QuerySchema extends object = object> {
  querySchema?: ClassConstructor<any>;
  query?: QuerySchema;

  constructor(
    protected readonly req: Request,
    protected readonly res: Response,
  ) {
    if (this.querySchema) {
      this.query = transvalidate(this.querySchema, this.req.query);
    }
  }

  getQuery(): QuerySchema {
    if (!this.query) {
      throw new Error(
        `Can't get query. Probably the querySchema is not provided.`,
      );
    }
    return this.query;
  }

  abstract handle(): Promise<unknown>;
}

2. 子类写法

直接按你期望的方式编写即可,不需要额外传入泛型参数:

import { Controller } from './controller';
import { GetCatsQuerySchema } from './schema/query.schema';

// 无需手动传入泛型参数
export class CatsController extends Controller {
  querySchema = GetCatsQuerySchema;

  handle(): Promise<unknown> {
    // this.getQuery() 仍然会返回准确的 GetCatsQuerySchema 类型,类型提示完全正常
    const query = this.getQuery();
    return Promise.resolve(undefined);
  }
}

注意事项

  • 要求TypeScript版本 ≥ 4.4,才能支持完整的子类属性反向类型推断
  • 现有代码中的GetCatsQuerySchema存在类型不匹配问题:age字段通过@Type(() => Number)转为数字类型,同时用@IsInt()做整数校验,但类型声明为string,建议修改为age?: number
  • 该实现不会损失任何类型安全性,所有类型校验和提示逻辑和原有写法完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 00:06:03