TypeScript类方法调用报错:Cannot read properties of undefined
问题:调用类方法时触发TypeError:Cannot read properties of undefined (reading 'onOpenMessage')
项目编译无错误,但在控制器中调用类方法时触发TypeError,提示Cannot read properties of undefined (reading 'onOpenMessage')。将私有方法onOpenMessage改为公有也无法解决问题,同类代码在其他项目可正常运行。
报错堆栈信息
TypeError: Cannot read properties of undefined (reading 'onOpenMessage') at WebSocket. (/Users/xxx/redqueen-middleware/src/controllers/websocket.ts:23:16) at WebSocket.onMessage (/Users/xxx/redqueen-middleware/node_modules/ws/lib/event-target.js:132:16) at WebSocket.emit (node:events:513:28) at Receiver.receiverOnMessage (/Users/xxx/redqueen-middleware/node_modules/ws/lib/websocket.js:1068:20) at Receiver.emit (node:events:513:28) at Receiver.dataMessage (/Users/xxx/redqueen-middleware/node_modules/ws/lib/receiver.js:517:14) at Receiver.getData (/Users/xxx/redqueen-middleware/node_modules/ws/lib/receiver.js:435:17) at Receiver.startLoop (/Users/xxx/redqueen-middleware/node_modules/ws/lib/receiver.js:143:22) at Receiver._write (/Users/xxx/redqueen-middleware/node_modules/ws/lib/receiver.js:78:10) at writeOrBuffer (node:internal/streams/writable:391:12) [ERROR] 16:46:06 TypeError: Cannot read properties of undefined (reading 'onOpenMessage')
相关代码
控制器代码(websocket.ts)
class WebsocketController { initWebsocket(websocket: WebSocket): void { //some code, works fine before calling method `onOpenMessage` this.onOpenMessage(); } private onOpenMessage(): void { //some code } } export default new WebsocketController();
tsconfig.json配置
{ "compilerOptions": { "module": "commonjs", "declaration": false, "noImplicitAny": false, "removeComments": true, "noLib": false, "allowSyntheticDefaultImports": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "target": "es6", "esModuleInterop": true, "lib": [ "dom", "es6", "esnext.asynciterable" ], "typeRoots": [ "./custom_typings", "./node_modules/@types" ], "sourceMap": true, "allowJs": true, "outDir": "./build", "baseUrl": "./src", "resolveJsonModule": true }, "include": [ "src/**/*", "config/**/*" ], "exclude": [ "node_modules", "**/*.spec.ts", "**/*.test.ts", "custom_typings" ] }
server.ts代码
import express from 'express'; import expressWs from 'express-ws'; import winston from 'winston'; import WebsocketController from './controllers/websocket'; export default function initServer() { const app = express(); const port = process.env.PORT; const router = express.Router(); global.websocketsList = []; expressWs(app); router.ws('/ws-request', WebsocketController.initWebsocket); app.use('/', router); app.listen(port, () => { winston.info(`Middleware server start on port ${port}`); }); }
解决方案
问题根源是**this上下文丢失**:在server.ts中直接传递WebsocketController.initWebsocket作为回调时,该方法的this不再绑定到控制器实例,调用时this为undefined,导致无法读取onOpenMessage属性。
有两种修复方式:
方式1:用箭头函数包裹回调
修改server.ts中的路由注册代码:
router.ws('/ws-request', (ws) => WebsocketController.initWebsocket(ws));
箭头函数会自动捕获当前上下文,确保initWebsocket中的this指向控制器实例。
方式2:手动绑定this到实例
同样修改路由注册代码:
router.ws('/ws-request', WebsocketController.initWebsocket.bind(WebsocketController));
通过bind方法强制将this绑定到控制器实例,避免上下文丢失。
两种方式都能解决问题,任选其一即可。
内容的提问来源于stack exchange,提问作者Oleksii Nechaiev
相关产品推荐
相关产品推荐

