Node Express项目中Typedi构造函数注入返回undefined 仅属性注入正常
typedi构造函数注入实例为undefined的解决方案
核心原因匹配
你遇到的构造函数注入失效、属性注入正常的场景,基本都是以下3个原因导致的,和你给出的补充条件完全契合:
- 未开启TypeScript的
emitDecoratorMetadata编译配置,构造函数参数的元数据无法生成,typedi无法识别要注入的参数 - 重复声明注入属性:构造函数参数用
private/protected/public修饰符时会自动生成类实例属性,额外在类中声明同名属性并加@Inject会导致注入逻辑冲突,最终覆盖为undefined - 手动实例化Service而非通过typedi的Container获取实例,构造函数参数没有被typedi自动注入
具体解决步骤
1. 检查tsconfig.json配置
确保compilerOptions中同时开启以下两个配置,缺一不可:
{ "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true // 其余原有配置保持不变 } }
属性注入不需要读取构造函数参数元数据,所以即使没开emitDecoratorMetadata也能正常运行,和你遇到的现象完全一致。
2. 修正类写法,删除重复的属性声明
构造函数注入不需要额外在类中声明同名属性加@Inject,正确写法如下:
import { Service, Inject } from 'typedi'; import { EventEmitter } from 'events'; @Service() export default class AuthService { constructor( @Inject("logger") private logger: any, // 替换为你实际的logger类型 @Inject("eventEmitter") private eventEmitter: EventEmitter ) {} // 原有业务方法保持不变 public async SignUp(userInputDTO: IUserInputDTO): Promise<{ user: IUser; token: string }> { try { //some code this.logger.silly("Hashing password"); const hashedPassword = await argon2.hash(userInputDTO.password, { salt }); this.logger.silly("Creating user db record"); this.eventEmitter.emit(userEvent.signUp); //some code return { user: { }, token: "myToken", }; } catch (e) { this.logger.error(e); throw e; } } }
3. 确认Service实例获取方式
必须通过typedi的Container API获取实例,禁止手动new:
// 正确写法 import { Container } from 'typedi'; import AuthService from './auth.service'; const authService = Container.get<AuthService>(AuthService); // 错误写法,会导致构造函数参数无值 // const authService = new AuthService();
验证方式
可以在构造函数内增加打印逻辑,确认注入是否生效:
constructor( @Inject("logger") private logger, @Inject("eventEmitter") private eventEmitter: EventEmitter ) { console.log('构造函数注入的logger:', logger); console.log('构造函数注入的eventEmitter:', eventEmitter); }
如果构造函数内打印有值,后续调用为undefined,100%是重复声明属性导致的覆盖问题。
内容的提问来源于stack exchange,提问作者Rensykes
相关产品推荐
相关产品推荐

