할 일 목록 화면이에요. 상단에 총 12건이 떠 있고, 제가 할 일을 하나 추가해요. 서버 응답을 기다리지 않고 숫자부터 올리려고 total + 1을 했는데, 화면에 총 121건이 떴어요. (순간 할 일이 백 개 넘게 생긴 줄 알았어요.)
이유는 이거였어요. PostgreSQL의 count(*)는 bigint이고, Node의 pg 드라이버는 bigint를 기본으로 문자열로 돌려줘요. JavaScript 숫자에는 64비트 정수가 다 안 들어가니까요. 그런데 행 타입은 제가 손으로 이렇게 적어 뒀어요.
type CountRow = { total: number };
const { rows } = await pool.query<CountRow>(
'SELECT count(*) AS total FROM todos WHERE done = false',
);
setTotal(rows[0].total + 1);
타입이 number라고 하니 에디터는 아무 말도 안 하고, 런타임에서는 '12' + 1이 문자열 이어 붙이기가 돼요.
고치는 방법은 두 가지가 보여요. SQL에서 count(*)::int로 캐스팅하거나, 코드에서 받은 값을 파싱하거나요. 쿼리가 몇 개 안 될 때는 캐스팅이 편해 보이는데, 다들 어느 쪽에 두세요?