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

使用fastify-decorators与TypeDI实现依赖注入时遇未定义错误

问题:fastify-decorators + TypeDI 依赖注入失败,this.userService 为 undefined

错误信息

Cannot read properties of undefined (reading 'getSomething')

相关代码

UserController.ts

import { Controller, GET } from "fastify-decorators";
import { Inject } from "typedi";
import { FastifyReply, FastifyRequest } from "fastify";
import { UserServiceImpl } from "@services/UserServiceImpl";

@Controller("/users")
export default class UserController {
  @Inject()
  private userService!: UserServiceImpl;

  @GET("/")
  async getUser(request: FastifyRequest, reply: FastifyReply) {
    const users = await this.userService.getSomething();
    reply.send(users);
  }
}

UserServiceImpl.ts(注:你提供的代码存在复制错误,以下为修正后的服务类示例)

import { Service } from "typedi";

@Service()
export class UserServiceImpl {
  async getSomething() {
    return [{ id: 1, name: "Test User" }];
  }
}

app.ts

import Fastify, { FastifyBaseLogger } from "fastify";
import { bootstrap } from "fastify-decorators";
import { resolve } from "path";
import logger from "@config/logger";
import { useContainer } from "@fastify-decorators/typedi";
import { Container } from "typedi";

export default function buildApp() {
  const app = Fastify({
    logger: logger as FastifyBaseLogger,
  });

  useContainer(Container);

  app.register(bootstrap, {
    directory: resolve(__dirname, "controllers"),
    mask: /Controller\.ts$/,
  });

  return app;
}

index.ts

import "reflect-metadata";
import { PORT } from "@config/env";
import buildApp from "./app";

const start = async () => {
  const app = buildApp();

  try {
    await app.listen({
      port: PORT,
      host: "0.0.0.0",
    });
  } catch (err) {
    app.log.error(err);
    process.exit(1);
  }
};

start();

文件夹结构

文件夹结构


可能的原因及解决方案

1. 服务类未标记为TypeDI可注入对象

你提供的UserServiceImpl.ts代码是错误的(复制了控制器代码),正确的服务类必须用TypeDI的@Service()装饰器标记,否则容器无法识别并创建该类的实例,@Inject()自然无法获取到对象,导致userService为undefined。

修正方案:在UserServiceImpl类上添加@Service()装饰器(如上面修正后的代码所示)。

2. 路径别名配置错误

你使用了@services/UserServiceImpl这类路径别名,需要确保tsconfig.json中正确配置了路径映射,否则会导致模块导入失败,间接引发注入失败。

检查tsconfig.json示例:

{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "@services/*": ["services/*"],
      "@config/*": ["config/*"]
    }
    // 其他配置项...
  }
}

3. 容器集成未生效

虽然你调用了useContainer(Container),但需确保依赖安装完整:

  • 确认已安装@fastify-decorators/typedi
  • 确认reflect-metadata在入口文件(index.ts)最顶部导入(你已满足此要求)

4. 上下文绑定问题(低概率)

如果fastify-decorators未正确绑定控制器的this上下文,也会导致this.userService为undefined。可尝试显式绑定:

// 方式1:使用箭头函数
@GET("/")
async getUser = (request: FastifyRequest, reply: FastifyReply) => {
  const users = await this.userService.getSomething();
  reply.send(users);
};

// 方式2:构造函数绑定
constructor() {
  this.getUser = this.getUser.bind(this);
}

内容的提问来源于stack exchange,提问作者Thiago Robles

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:45:02