TypeScript报错:.filter无调用签名,如何移除房间内设备?
解决TypeScript中“.filter无调用签名”错误
问题场景
在处理设备断开连接逻辑时遇到TypeScript错误,具体提示:
This expression is not callable.
Type 'IDevice' has no call signatures.ts(2349)
完整代码
const rooms: Record<string, Record<string, IDevice>> = {}; interface IDevice { deviceId: string; deviceName?: string; } interface IRoomParams extends IDevice { userId: string; } interface ISendRequestParams { userId: string; options: any; requestId: string; } interface IReturnRequestParams { userId: string; data: any; requestId: string; error: any; } const joinRoom = ({ userId, deviceId, deviceName }: IRoomParams) => { if (!rooms[userId]) rooms[userId] = {}; rooms[userId][deviceId] = { deviceId, deviceName }; socket.join(userId); io.sockets.to(userId).emit('get-devices', { userId, participants: rooms[userId] }); socket.on('disconnect', () => { console.log(`user left the room: roomId[${userId}], device[${deviceId}], deviceName[${deviceName}]`); rooms[userId] = rooms[userId]?.filter((id) => id !== deviceId); socket.to(userId).emit('device-disconnected', deviceName); }); };
问题原因
rooms的类型是Record<string, Record<string, IDevice>>,意味着rooms[userId]是一个键值对对象,而.filter()是数组专属方法,对象本身没有这个方法,因此TypeScript抛出调用签名不存在的错误。
解决方案
方案1:直接删除对象属性(推荐)
要移除指定设备,直接用delete操作符删除对应deviceId的属性即可,这是处理对象键值对最直接的方式:
socket.on('disconnect', () => { console.log(`user left the room: roomId[${userId}], device[${deviceId}], deviceName[${deviceName}]`); // 删除目标设备 delete rooms[userId]?.[deviceId]; // 可选:通知房间内其他用户更新设备列表 socket.to(userId).emit('get-devices', { userId, participants: rooms[userId] }); socket.to(userId).emit('device-disconnected', deviceName); });
方案2:转数组过滤后转回对象
如果偏好类似数组的过滤逻辑,可以先把对象转为键值对数组,过滤后再转回对象:
socket.on('disconnect', () => { console.log(`user left the room: roomId[${userId}], device[${deviceId}], deviceName[${deviceName}]`); if (rooms[userId]) { // 对象转数组 → 过滤 → 转回对象 rooms[userId] = Object.fromEntries( Object.entries(rooms[userId]).filter(([id]) => id !== deviceId) ); } socket.to(userId).emit('device-disconnected', deviceName); });
内容的提问来源于stack exchange,提问作者Jerry Seigle
相关产品推荐
相关产品推荐

