문제 상황

WebSocket을 통해 메시지를 수신하는 과정에서 다음과 같은 TypeScript 에러들이 연속적으로 발생했습니다.

1차 에러: 메시지 타입 정의 누락


// 에러 메시지
'string' 형식에 'messageType' 속성이 없습니다.ts(2339)
'string' 형식에 'payload' 속성이 없습니다.ts(2339)

2차 에러: 타입 불일치


// 에러 메시지
'(message: WebSocketMessage) => void' 형식의 인수는 '(message: string) => void'
형식의 매개 변수에 할당될 수 없습니다.

3차 에러: JSON 파싱 실패


// 에러 메시지
Failed to parse WebSocket message: SyntaxError: "[object Object]" is not valid JSON

문제 해결 과정

1단계: WebSocket 메시지 타입 정의

먼저 WebSocket을 통해 수신되는 메시지의 타입을 정의했습니다.

interface WebSocketMessage {
  messageType: string;
  payload: RoomPayload;
}

interface RoomPayload {
  allReady: boolean;
  currentPlayers: Player[];
  host: string;
  readyStatus: { [key: string]: boolean };
  roomId: string;
  status: string;
}

2단계: 타입 불일치 해결 시도

subscribeToRoom의 콜백 함수 시그니처와 일치하도록 string 타입으로 수정하고, JSON 파싱을 추가했습니다.

subscribeToRoom(String(roomId), (message: string) => {
  try {
    const parsedMessage = JSON.parse(message) as WebSocketMessage;
    if (parsedMessage.messageType === 'PLAYER_JOIN') {
      setRoomData(parsedMessage.payload);
    }
  } catch (error) {
    console.error('Failed to parse WebSocket message:', error);
  }
});

3단계: 최종 해결

메시지가 이미 JavaScript 객체로 파싱되어 있음을 확인하고, any 타입과 타입 단언을 사용하여 해결했습니다.

subscribeToRoom(String(roomId), (message: any) => {
  const wsMessage = message as WebSocketMessage;
  if (wsMessage.messageType === 'PLAYER_JOIN') {
    setRoomData(wsMessage.payload);
  }
});

이를 통해서 배운 점