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

如何从工厂函数获取类类型为NestJS动态控制器指定TypeScript类型?

解决NestJS动态控制器工厂函数的TypeScript类型推断问题

可以通过优化工厂函数的类型定义和控制器生成逻辑的泛型约束,让TypeScript正确推断出动态生成的DTO类类型,避免出现any。以下是具体解决方案:

1. 修正统一DTO工厂的类型定义

首先明确类构造函数的泛型类型,优化工厂函数的条件返回类型,让TypeScript能准确追踪不同操作对应的返回类型:

// 定义带泛型的类构造函数类型
type ClassConstructor<T = any> = new (...args: any[]) => T;

// 模拟原统一响应DTO包装函数(根据实际逻辑调整)
function UniformResponseDto<T extends ClassConstructor>(DTO: T) {
  class WrappedDTO {
    data!: InstanceType<T>;
  }
  return WrappedDTO;
}

// 优化后的条件返回类型
type ConditionalReturnType<T extends ClassConstructor | ClassConstructor[], O extends string> = 
  O extends 'list' 
    ? T extends ClassConstructor[] 
      ? Array<InstanceType<T[number]>> 
      : never // 列表场景强制要求传入数组形式的DTO
    : ReturnType<typeof UniformResponseDto<T extends ClassConstructor ? T : never>>;

// 修正后的工厂函数
function factory<T extends ClassConstructor | ClassConstructor[], O extends string>(
  DTO: T, 
  op: O
): ConditionalReturnType<T, O> {
  if (op === 'list') {
    return DTO as ConditionalReturnType<T, O>;
  }
  return UniformResponseDto(DTO as ClassConstructor) as ConditionalReturnType<T, O>;
}

2. 优化动态控制器生成函数

将工厂函数的类型约束从宽泛的any改为具体的typeof factory,让TypeScript能正确推断生成的DTO类类型:

function createController<ModelDTOType extends ClassConstructor>(
  ModelDTO: ModelDTOType,
  uniformDTOFactory: typeof factory
) {
  // 现在TypeScript能正确推断这两个变量的类型,不再是any
  const RetrieveDTO = uniformDTOFactory(ModelDTO, 'retrieve');
  const ListDTO = uniformDTOFactory([ModelDTO], 'list');

  type RetrieveDTOType = InstanceType<typeof RetrieveDTO>;
  type ListDTOType = InstanceType<typeof ListDTO>;

  class DynamicController {
    async list(): Promise<ListDTOType> {
      return [{ id: 1 }] as ListDTOType;
    }

    async retrieve(): Promise<RetrieveDTOType> {
      return { data: { id: 1 } } as RetrieveDTOType;
    }
  }

  return DynamicController;
}

关键修改说明

  • 给ClassConstructor添加泛型参数,明确类的实例类型,为后续类型推断提供基础
  • 优化ConditionalReturnType,区分列表/单条数据场景的返回类型,让TypeScript能精准识别
  • 控制器生成函数中,将uniformDTOFactory的类型绑定到具体的factory函数类型,避免泛型丢失导致的any推断
  • 简化控制器函数的泛型参数,去掉不必要的抽象约束,提升类型推断的准确性

经过上述调整,RetrieveDTOType和ListDTOType会被正确推断为对应的类实例类型,控制器方法的返回类型也会受到TypeScript的类型校验,不再是any。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 03:21:15