처음 TypeScript 도입을 제안했을 때, 팀장님의 반응은 이랬다. "그거 배우는 데 얼마나 걸려? 우리 스프린트 일정 있잖아." 그리고 시니어 개발자 K님은 "자바스크립트가 뭐가 문제야, 우리 3년 동안 잘 썼는데"라며 미간을 찌푸리셨다. 2024년 초, 우리 팀의 TypeScript 도입기는 그렇게 시작됐다.
결론부터 말하자면, 6개월 뒤 팀 전체가 TypeScript를 쓰고 있다. 그런데 그 과정이 기술 블로그에서 말하는 것처럼 "생산성 향상, 버그 감소, 팀 만족도 급등"의 해피엔딩이었냐고 물으면… 솔직히 그렇게 단순하지 않았다.

왜 TypeScript를 꺼냈나 — 진짜 이유
공식적인 이유는 "코드 품질 개선"이었지만, 솔직한 이유는 따로 있었다. 우리 팀 Next.js 프로젝트에 버그가 너무 자주 났다. 특히 API 응답값을 그냥 data.user.name으로 접근하다가 undefined가 터지는 류의 버그. QA 단계에서도 못 잡고 프로덕션에서 터지는 게 한 분기에 세 번이었다.
제안서를 쓰면서 나름 근거를 마련했다. StackOverflow 개발자 설문에서 TypeScript가 몇 년째 "가장 사랑받는 언어" 상위권을 유지하고 있다는 것, 우리가 참고하는 오픈소스 라이브러리들이 대부분 TS로 전환했다는 것, 그리고 신규 팀원 온보딩 때 코드 이해에 걸리는 시간을 줄일 수 있다는 것. 팀장님이 마지막 항목에서 눈빛이 달라지셨다. 우리 팀은 그 분기에 신규 입사자가 두 명 예정이었으니까.
1단계: 설득의 벽 — 사람이 제일 어려웠다
기술 도입에서 제일 어렵다고 하면 흔히 "러닝커브"를 꼽는다. 틀린 말은 아닌데, 실제로 더 어려운 건 사람이었다.
가장 설득하기 어려웠던 분은 K님이었다. 10년 차 시니어로, JS 숙련도가 팀에서 제일 높으셨다. 그분 입장에서는 TypeScript가 "내 능력치를 제한하는 도구"처럼 느껴지셨던 것 같다. 실제로 하신 말씀이 "나는 이미 머릿속으로 타입을 다 알고 있거든. 굳이 코드에 적어야 해?"였다.
"TypeScript는 내가 이미 아는 걸 코드에 증명해야 하는 느낌이야. 오히려 답답해."
— K님, 도입 초기 솔직 피드백이 말이 사실 굉장히 타당한 지적이었다. 숙련된 JS 개발자에게 TypeScript는 처음에 분명히 족쇄처럼 느껴진다. 나는 반박하는 대신 "그럼 신규 팀원이 K님 코드를 읽을 때도 그게 가능할까요?"라고 물었고, 거기서 대화가 달라지기 시작했다.
2단계: 실제 마이그레이션 — 예상보다 훨씬 험했다
파일럿이 성공적으로 끝나고 전체 마이그레이션을 시작했다. allowJs: true, checkJs: false로 설정해서 JS와 TS를 공존시키는 전략이었다. 이론적으로는 완벽했다.
{
"compilerOptions": {
"strict": false, // 처음엔 느슨하게
"allowJs": true, // JS 파일도 허용
"checkJs": false, // JS는 타입 체크 스킵
"noImplicitAny": false, // any 허용 (임시)
"skipLibCheck": true, // 라이브러리 체크 스킵
"target": "ES2020",
"moduleResolution": "bundler"
}
}
문제는 레거시 코드가 예상보다 훨씬 더 "암묵적 타입"에 의존하고 있었다는 것이다. 대표적인 지옥 케이스들:
1.
Object.assign()으로 마구 합쳐진 객체들 — 타입 추론 불가2. 서버에서 오는 응답을
as any 없이는 도저히 못 쓰는 케이스들3. 동적으로 키를 추가하는 패턴 (
obj[dynamicKey] = value)특히 세 번째가 제일 고통스러웠다. 우리 코드베이스 곳곳에 obj[someString] = someValue 패턴이 있었는데, 이걸 Record<string, unknown>으로 처리하면 다운스트림에서 또 타입 에러가 터졌다. 한 파일을 고치면 연쇄적으로 다른 파일에서 에러가 났다. 어느 날은 타입 에러 수정 커밋을 하루에 23개 올렸다.
3단계: 팀 내 갈등이 수면 위로
마이그레이션 3주 차에 팀 회고에서 분위기가 터졌다. 한 팀원이 "TypeScript 때문에 이번 스프린트 속도가 30% 이상 떨어진 것 같다"고 공개적으로 말했다. 틀린 말이 아니었다. 실제로 그 주 속도가 느려졌으니까.
| 항목 | JS 시절 | TS 전환 중 (3주차) | TS 정착 후 (6개월) |
|---|---|---|---|
| 기능 개발 속도 | 기준치 | –28% | +12% |
| PR 리뷰 시간 | 평균 45분 | 평균 80분 | 평균 28분 |
| 프로덕션 버그 (타입 관련) | 분기 3건 | 전환 중 집계 의미 없음 | 0건 |
| 신규 팀원 온보딩 | 약 3주 적응 | — | 약 1.5주 적응 |
| 팀원 만족도 (자체 설문) | 6.2 / 10 | 4.1 / 10 | 7.8 / 10 |
이 수치를 보면 "전환 중에 진짜 힘들었구나"가 느껴질 것이다. 솔직히 나는 그 3주 차 회고 직후 "내가 괜히 TS 꺼낸 건가" 하는 생각을 했다. 팀원들의 얼굴이 피곤해 보였고, 내가 만든 문제인 것 같았다.
진짜 도움이 됐던 것들 — 과장 없이
6개월이 지난 지금, 팀에서 실제로 효과를 체감하는 포인트를 솔직하게 정리한다.
주목할 것은 마지막 항목이다. TypeScript가 초기 개발 속도를 높여준다고 말하는 사람들이 있는데, 우리 팀 경험에서는 그 효과가 크지 않았다. 빠른 건 "기능 개발 속도"가 아니라 "코드 읽기 속도"와 "디버깅 속도"였다. 구분이 중요하다.
// Before: 이 함수가 뭘 반환하는지 코드 뜯어봐야 앎
async function fetchUserProfile(id) {
const data = await api.get(`/users/${id}`);
return data; // 이게 뭔지 신규 팀원은 모름
}
// After: 계약서처럼 명확
interface UserProfile {
id: string;
name: string;
email: string;
role: 'admin' | 'member' | 'viewer';
createdAt: Date;
}
async function fetchUserProfile(id: string): Promise<UserProfile> {
const data = await api.get<UserProfile>(`/users/${id}`);
return data;
}
하지 말걸 싶었던 실수들
돌이켜보면 아쉬운 결정들이 있다. 비슷한 상황의 팀에게 솔직히 전달하고 싶어서 적는다.
초기에
.js → .ts 확장자를 한꺼번에 바꾸고 에러를 잡으려 했다. 결과: 에러 847개, 팀 멘붕. 컴포넌트 단위, 기능 단위로 작게 쪼갰어야 했다."어차피 할 거면 제대로"라는 생각에 strict 모드를 2주 만에 켰다가 팀 전체가 일주일을 에러 수정만 했다. 최소 2~3개월은 느슨하게 가야 했다.
"쓰다 보면 배우겠지" 생각이 가장 컸던 실수. Generic 문법, type vs interface 차이, utility types 같은 개념을 1~2주 미니 스터디로 먼저 했어야 했다.
@ts-ignore 사용 규칙 만들기@ts-ignore를 쓸 때 반드시 TODO 커멘트와 이슈 번호를 달도록 규칙화했다. 나중에 technical debt 추적이 쉬워졌다.6개월 후, K님의 말
가장 반대하셨던 K님이 최근 스프린트 회고에서 이렇게 말씀하셨다. "솔직히 아직도 타입 쓰는 게 번거롭긴 한데, 저번에 신입 C가 내 코드 수정할 때 타입 덕분에 실수 없이 짠 거 보고 생각이 좀 바뀌었어."
이게 TypeScript 도입의 진짜 가치라고 생각한다. 지금 잘하는 사람을 위한 도구가 아니라, 팀 전체가 일관된 수준으로 협업하게 해주는 도구. 그 관점 전환이 없었다면 K님을 설득하지 못했을 것이다.
TypeScript는 개인의 실력을 높이는 도구가 아니라, 팀의 최저 코드 품질 라인을 끌어올리는 도구다.
— 6개월 마이그레이션 후 내 결론TypeScript 팀 도입을 고민하는 분들께
한 줄 요약을 해달라면: 기술보다 사람 설득에 더 많은 에너지를 써라. 그리고 완벽한 전환을 목표로 하지 말고, 다음 세 가지만 지키면 된다.
① 신규 파일부터 TS로 — 기존 코드는 건드리지 않기
② strict: false로 시작, 3개월 후 항목별로 켜기
③ 팀원 중 한 명은 "TS 전도사"로 지정해 Q&A 창구 만들기
④ 속도 저하를 경영진/팀장에게 미리 선언하기 (안 하면 나중에 욕먹음)
⑤
any를 쓴 것에 죄책감 갖지 않기 — 점진적으로 줄이면 된다TypeScript 자체는 훌륭한 도구다. 하지만 "TS를 쓰면 버그가 없어진다"는 말은 반만 맞다. 정확히는 "TS를 쓰면 특정 유형의 버그가 컴파일 타임으로 당겨진다"이다. 런타임 로직 버그, 비즈니스 로직 오류는 TypeScript가 못 잡는다. 그 점을 팀에 분명히 해두지 않으면 "TS 써도 버그 나네?"라는 실망으로 이어진다.
우리 팀은 지금도 완벽하지 않다. 타입 커버리지 92%는 나머지 8%가 여전히 any라는 뜻이고, strict 옵션 일부는 아직 비활성화 상태다. 그래도 6개월 전보다 훨씬 나은 코드베이스에서 일하고 있다는 건 팀 전체가 동의한다.
💬 여러분의 팀은 어떠셨나요?
TypeScript 도입을 시도했거나 고민 중이신 분들, 혹은 반대로 "우리 팀은 안 해도 잘 돼"라는 분들 — 댓글로 팀 이야기를 들려주세요. 특히 시니어 개발자 설득 경험담이 있으시다면 정말 궁금합니다. 그리고 혹시 any 남발로 결국 TS를 포기한 케이스도 있으시다면, 그것도 소중한 경험이니 부끄러워 말고 공유해 주세요. 🙏
'개발자 > 기술스택 도구' 카테고리의 다른 글
| Next.js 실무 도입 후 1년, 솔직하게 달라진 점들을 써봅니다 (0) | 2026.06.12 |
|---|