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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 22:06:02