JS/TS에서 == 대신 ===만 써야 하는 이유 (feat. ESLint 최적 설정)
자바스크립트 커뮤니티에서 “무조건 ===를 쓰라”는 조언은 이제 상식에 가깝습니다. 하지만 실무에서는 여전히 ==가 섞여 들어오곤 합니다. 특히 최근 **AI 보조 도구(Copilot 등)**가 생성하는 코드에서 이 비교 연산자가 혼용되는 현상이 잦아지고 있습니다.
오늘은 왜 ===가 표준이 되었는지, 그리고 팀 단위 프로젝트에서 이를 강제하기 위한 ESLint 최적 설정법까지 깊이 있게 다뤄보겠습니다.
목차
- == vs ===: 무엇이 다른가?
- 왜 웬만하면 ===만 사용해야 할까?
- AI는 왜 자꾸 이 차이를 헷갈릴까?
- TypeScript에서의 타입 좁히기와 null 체크
- 최적의 가이드: ESLint eqeqeq 규칙 설정
- 자주 묻는 질문(FAQ)
== vs ===: 무엇이 다른가?
자바스크립트 엔진은 두 값을 비교할 때 서로 다른 두 가지 알고리즘을 사용합니다.
1. 느슨한 비교 (Loose Equality, ==)
두 값의 **타입이 다르면 암묵적으로 타입을 변환(Coercion)**한 뒤 비교합니다.
0 == false; // true
'' == 0; // true
null == undefined; // true
2. 엄격한 비교 (Strict Equality, ===)
타입 변환을 허용하지 않습니다. 값과 타입이 모두 일치해야만 true를 반환합니다.
0 === false; // false
'1' === 1; // false
왜 웬만하면 ===만 사용해야 할까?
가장 큰 이유는 동작의 예측 가능성입니다. ==는 개발자가 의도하지 않은 형변환을 일으켜 감추어진 버그를 만듭니다.
[10] == 10은true이지만,[10, 20] == "10,20"도true입니다.- 이런 복잡한 변환 규칙을 모든 팀원이 완벽히 숙지하고 코딩하기란 불가능합니다. 따라서 “타입 변환은 명시적으로(Explicit), 비교는 엄격하게(Strict)” 하는 것이 클린 코드의 핵심입니다.
AI는 왜 자꾸 이 차이를 헷갈릴까?
최신 AI 모델들이 ==를 자주 추천하는 이유는 크게 세 가지입니다.
- 데이터 오염: AI가 학습한 방대한 오픈소스 데이터에는
===가 표준이 되기 전의 레거시 코드가 대량 포함되어 있습니다. - 확률적 예측:
if (input ==뒤에 관습적으로null이 오는 코드가 많다 보니, 확률적으로==를 더 자연스러운 토큰으로 인식하기도 합니다. - 간결함 추구: AI는 종종 가독성보다 코드의 짧은 길이를 우선시하여
(a === null || a === undefined)대신(a == null)을 제안합니다.
TypeScript에서의 타입 좁히기와 null 체크
질문하신 시나리오를 TypeScript 관점에서 분석해 보겠습니다.
let a: number | undefined | null;
// 느슨한 비교(==)를 사용한 null 체크
if (a == null) {
// TypeScript는 여기서 a를 null | undefined로 똑똑하게 추론합니다.
} else {
// 여기서는 a가 확실히 'number'임을 보장합니다.
console.log(typeof a); // "number"
}
사실 a == null은 null과 undefined를 동시에 체크하는 매우 흔한 관용구입니다. 하지만 협업 시 팀원들 간의 혼선을 줄이기 위해 이마저도 금지하는 팀이 많습니다.
최적의 가이드: ESLint eqeqeq 규칙 설정
인간(혹은 AI)의 실수를 방지하는 가장 좋은 방법은 자동화된 도구를 쓰는 것입니다. ESLint의 eqeqeq 규칙을 활용하세요.
1. 추천 설정: always (가장 엄격함)
모든 상황에서 ===와 !==를 강제합니다. 예외를 허용하지 않아 가장 안전합니다.
// .eslintrc.json
{
"rules": {
"eqeqeq": ["error", "always"]
}
}
2. 현실적인 타협안: smart
거의 모든 경우에 ===를 강제하지만, 두 리터럴 값을 비교하거나 null과 비교할 때는 ==를 허용합니다.
{
"rules": {
"eqeqeq": ["error", "smart"]
}
}
3. 필자의 추천: always + 명시적 체크
보안과 명확성을 위해 always를 사용하고, null/undefined 체크는 명시적으로 작성하는 것을 권장합니다.
// Good (명확함)
if (val === null || val === undefined) { ... }
// Better (Optional Chaining/Nullish Coalescing 활용)
if (val ?? true) { ... }
자주 묻는 질문(FAQ)
Q. Object.is()는 언제 쓰나요?
Object.is(NaN, NaN)은 true를 반환합니다(===는 false). 매우 특수한 수학적 비교나 React의 상태 변경 감지 로직이 필요한 경우에만 제한적으로 사용합니다.
Q. ==가 ===보다 빠른가요?
이론적으로 ===는 타입을 먼저 체크하므로 타입이 다를 경우 더 빨리 종료될 수 있습니다. 하지만 현대 브라우저 엔진에서 이 차이는 측정 불가능할 정도로 미미합니다.
Q. 모든 프로젝트에 eqeqeq 에러를 켜야 하나요?
네, 신규 프로젝트라면 반드시 error로 설정하세요. 기존 프로젝트라면 우선 warn으로 시작하여 점진적으로 수정해 나가는 것을 추천합니다.
더 상세한 규칙 설명은 ESLint 공식 문서: eqeqeq에서 확인할 수 있습니다.
댓글을 불러오는 중...