TypeScript项目中Cannot read properties of undefined(reading 'userService')问题排查
问题分析与解决方案
错误根源
你遇到的TypeError: Cannot read properties of undefined (reading 'userService')是因为方法的this上下文丢失:当你把this.userController.findAllUsers直接作为回调传给Express的router.get时,该方法的this不再指向UserController的实例,而是变成了undefined(严格模式下),导致无法访问this.userService。
另外你的代码还有两个小问题需要修正:
UserService的findAll方法使用了await,但没有声明为async,会触发语法错误UserController调用findAll时没有加await,会返回Promise而不是实际的用户数据
解决方案
方案1:路由中用箭头函数绑定上下文
修改UserRoute的initializeRoutes方法,用箭头函数包裹回调,确保this指向UserController实例:
class UserRoute implements Routes { public path = '/users'; public router = Router() public userController = new UserController() constructor(){ this.initializeRoutes() } initializeRoutes() { // 用箭头函数包裹,保留this上下文 this.router.get(`${this.path}`, (req, res, next) => this.userController.findAllUsers(req, res, next)) } }
方案2:在UserController构造函数中绑定this
在UserController的构造函数里,把findAllUsers方法的this绑定到当前实例:
import { UserRepository } from "../repositories/userRepository" import { NextFunction, Request, Response } from "express" import UserService from "../services/userService" class UserController { public userService = new UserService() constructor() { // 绑定this到实例 this.findAllUsers = this.findAllUsers.bind(this) } async findAllUsers(request: Request, response: Response, next: NextFunction) { // 加上await获取实际数据 const users = await this.userService.findAll() response.json(users) } } export default UserController
方案3:用类字段箭头函数定义方法
把findAllUsers定义为箭头函数,这样this会始终指向UserController实例:
import { UserRepository } from "../repositories/userRepository" import { NextFunction, Request, Response } from "express" import UserService from "../services/userService" class UserController { public userService = new UserService() // 箭头函数自动绑定this findAllUsers = async (request: Request, response: Response, next: NextFunction) => { const users = await this.userService.findAll() response.json(users) } } export default UserController
修正UserService的async声明
别忘了给UserService的findAll方法加上async关键字:
class UserService { // 加上async关键字 public async findAll(){ return await UserRepository.find({}) } } export default UserService;
内容的提问来源于stack exchange,提问作者Alvanxl
相关产品推荐
相关产品推荐

