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

TypeScript未校验Nest模块工厂函数返回类的forRoot等方法入参类型

解决方案

核心问题是你将函数返回值设为any导致TypeScript丢失了类静态方法的类型推导,只需要定义对应模块接口作为返回值类型即可。

第一步:定义模块返回类型接口

先声明泛型接口匹配你创建的动态模块类的结构:

import type { DynamicModule, Type, ModuleAsyncOptions, ModuleOptionsFactory, Provider } from '@nestjs/common';

export interface HybridAuthModule<T> {
  /**
   * 同步配置模块
   */
  forRoot(options: T): DynamicModule;
  /**
   * 异步配置模块
   */
  forRootAsync(options: ModuleAsyncOptions<ModuleOptionsFactory<T>, T>): DynamicModule;
  /**
   * 类构造函数签名(必填,匹配类类型约束)
   */
  new (): object;
}

第二步:修改工厂函数返回值类型

把原来函数的返回值类型从any替换为上面定义的HybridAuthModule<T>:

export function createHybridAuthModule<T>(
  providerToken: string,
  // 可选优化:如果是passport策略可以替换为更具体的Type<PassportStrategy>
  strategy: Type<any>
): HybridAuthModule<T> {
  @Module({})
  class NestHybridAuthModule {
    static forRoot(options: T): DynamicModule {
      return {
        module: NestHybridAuthModule,
        providers: [
          {
            provide: providerToken,
            useValue: options,
          },
          strategy,
        ],
      };
    }

    static forRootAsync(
      options: ModuleAsyncOptions<ModuleOptionsFactory<T>, T>
    ): DynamicModule {
      return {
        module: NestHybridAuthModule,
        providers: [...this.createAsyncProviders(options), strategy],
      };
    }

    private static createAsyncProviders(
      options: ModuleAsyncOptions<ModuleOptionsFactory<T>, T>
    ): Provider[] {
      if (options.useExisting || options.useFactory) {
        return [this.createAsyncOptionsProvider(options)];
      }
      const useClass = options.useClass as Type<ModuleOptionsFactory<T>>;
      return [
        this.createAsyncOptionsProvider(options),
        {
          provide: useClass,
          useClass,
        },
      ];
    }

    private static createAsyncOptionsProvider(
      options: ModuleAsyncOptions<ModuleOptionsFactory<T>, T>
    ): Provider {
      if (options.useFactory) {
        return {
          provide: providerToken,
          useFactory: options.useFactory,
          inject: options.inject || [],
        };
      }

      const inject = [
        (options.useClass || options.useExisting) as Type<
          ModuleOptionsFactory<T>
        >,
      ];

      return {
        provide: providerToken,
        useFactory: async (optionsFactory: ModuleOptionsFactory<T>) =>
          await optionsFactory.createModuleOptions(),
        inject,
      };
    }
  }

  return NestHybridAuthModule;
}

效果验证

修改完成后,你调用TwitterAuthModule.forRoot、TwitterAuthModule.forRootAsync时,TypeScript会自动关联你传入的泛型TwitterAuthModuleOptions作为参数校验规则,参数缺失、类型不匹配、传入未定义属性都会直接抛出类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 03:27:03