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
相关产品推荐
相关产品推荐

