타입스크립트, 정말 퇴출될까?
좀 지난 이야기지만 개발자 커뮤니티에서 뜨거운 논쟁이 벌어지고 있습니다. Ruby on Rails의 창시자 David Heinemeier Hansson(DHH)이 hotwired/turbo 프로젝트에서 TypeScript를 제거하면서 시작된 이 논쟁은 "TypeScript는 과연 필요한가?"라는 근본적인 질문을 던지고 있죠.
TypeScript는 2012년 마이크로소프트에서 출시한 이후, JavaScript에 정적 타입을 추가해 대규모 프로젝트의 유지보수성을 높여주는 도구로 자리매김했습니다. 하지만 DHH의 결정 이후, Svelte 등 다른 프로젝트에서도 TypeScript 제거를 검토하면서 개발자들은 혼란에 빠졌어요.
이번 글에서는 TypeScript를 둘러싼 찬반 논쟁을 균형있게 살펴보고, 여러분의 프로젝트에 TypeScript가 정말 필요한지 판단할 수 있는 기준을 제시해드리겠습니다.
TypeScript를 반대하는 목소리
DHH가 Turbo 8에서 TypeScript를 제거한 이유
DHH는 자신의 블로그 글 "Turbo 8 is dropping TypeScript"에서 제거 결정의 배경을 솔직하게 밝혔습니다. 그의 주장을 요약하면 다음과 같아요:
“TypeScript는 내 개발 경험에 기쁨을 더하기보다는 방해가 됩니다. 명시적인 컴파일 단계가 필요할 뿐만 아니라, 타입 체조(type gymnastics)로 코드를 오염시키죠. 쉬워야 할 것들이 어려워지고, 어려운 것들은 결국 any가 되어버립니다.”
DHH는 ES6 이후 JavaScript가 충분히 성숙한 언어가 되었다고 주장합니다. 특히 클래스 문법과 다양한 개선사항들이 추가되면서, JavaScript 자체만으로도 충분히 즐거운 개발 경험을 제공한다는 거예요.
코드 오염과 복잡성 문제
TypeScript 반대론자들이 가장 자주 언급하는 문제는 바로 '코드 오염’입니다. 간단한 JavaScript 코드가 TypeScript로 작성되면 타입 정의로 인해 가독성이 떨어지는 경우가 많아요.
// TypeScript
function processUser(user: User & { permissions: Permission[] }): Promise<ProcessedUser | null> {
// 구현
}
// JavaScript
function processUser(user) {
// 구현
}
위 예시처럼 TypeScript는 타입 정의를 위해 추가적인 코드가 필요합니다. 소규모 프로젝트나 프로토타입 단계에서는 이러한 타입 정의가 오히려 개발 속도를 늦출 수 있죠.
컴파일 시간과 빌드 프로세스
TypeScript는 브라우저에서 직접 실행될 수 없기 때문에 JavaScript로 변환하는 컴파일 과정이 필수입니다. 프로젝트 규모가 커질수록 이 컴파일 시간은 점점 늘어나게 되고, 개발 워크플로우에 부담을 주게 돼요.
DHH는 "JavaScript는 브라우저에서 실행되는 언어"라는 점을 강조하며, 도구 없이 자유롭게 코드를 작성할 수 있다는 것이 큰 축복이라고 말합니다.
TypeScript를 지지하는 이유
유지보수성과 확장성
TypeScript의 가장 큰 장점은 대규모 프로젝트에서의 유지보수성입니다. 타입 시스템은 코드의 의도를 명확하게 표현하고, 리팩토링 시 발생할 수 있는 오류를 사전에 방지해줘요.
interface UserProfile {
id: string;
name: string;
email: string;
createdAt: Date;
}
function updateUserEmail(profile: UserProfile, newEmail: string): UserProfile {
return {
...profile,
email: newEmail
};
}
위 코드에서 만약 UserProfile 인터페이스가 변경되면, TypeScript는 영향을 받는 모든 코드를 즉시 알려줍니다. 수백 개의 파일을 일일이 확인할 필요가 없죠.
에러 감소와 안정성
JavaScript는 런타임에 타입 에러가 발생합니다. 프로덕션 환경에서 사용자가 에러를 만날 수 있다는 뜻이에요. 반면 TypeScript는 컴파일 단계에서 이런 에러를 잡아냅니다.
function calculateTotal(price: number, quantity: number): number {
return price * quantity;
}
calculateTotal("100", 5); // 컴파일 에러: string은 number에 할당할 수 없습니다
제로초님은 "대형 프로젝트에서 TypeScript는 안정적 개발 환경 구축에 필수적"이라고 강조했습니다. 서비스 안정성이 중요한 엔터프라이즈 환경에서는 이런 사전 에러 방지가 매우 중요하죠.
팀 협업과 개발자 경험
TypeScript는 IDE의 자동완성, 리팩토링 도구, 실시간 에러 체크 등 뛰어난 개발 도구 지원을 제공합니다. 특히 팀 프로젝트에서 다른 개발자의 코드를 이해하고 사용할 때 타입 정의는 살아있는 문서 역할을 해요.
/**
* 사용자 데이터를 검증하고 처리합니다
*/
function validateUser(user: User): ValidationResult {
// IDE가 User 타입의 모든 속성을 자동완성해줍니다
if (!user.email.includes('@')) {
return { valid: false, error: 'Invalid email' };
}
return { valid: true };
}
새로운 팀원이 합류했을 때, 타입 정의만 봐도 함수가 어떤 인자를 받고 무엇을 반환하는지 명확하게 알 수 있습니다.
엔터프라이즈 환경에서의 가치
대기업이나 복잡한 비즈니스 로직을 다루는 프로젝트에서 TypeScript의 가치는 더욱 빛을 발합니다. 수백 명의 개발자가 협업하고, 수년간 유지보수해야 하는 코드베이스에서는 타입 안정성이 필수적이에요.
실제로 Microsoft, Google, Airbnb 같은 대기업들이 TypeScript를 적극적으로 도입한 이유도 바로 여기에 있습니다.
개발자 커뮤니티의 반응
엇갈린 의견들
DHH의 TypeScript 제거 결정은 개발자 커뮤니티에서 뜨거운 논쟁을 불러일으켰습니다. 한국 개발자 커뮤니티에서도 의견이 극명하게 갈렸어요.
찬성하는 입장:
- “작은 프로젝트에서는 TypeScript가 오버엔지니어링이다”
- “JavaScript의 유연성이 TypeScript의 엄격함보다 낫다”
- “컴파일 단계가 없는 것이 개발 속도를 높인다”
반대하는 입장:
- “대형 프로젝트에서는 TypeScript 없이 유지보수가 불가능하다”
- “타입 안정성은 선택이 아닌 필수다”
- “초기 러닝커브는 있지만 장기적으로는 이득이다”
Turbo에서 TypeScript 제거 작업이 merge 되었을 때 반응은 대체로 부정적이었습니다. 많은 개발자들이 이 결정에 우려를 표명했죠.
조코딩님의 의견
유명 유튜버 조코딩님은 "Svelte에서도 TypeScript가 퇴출됐다"며, 생산성에 방해가 된다는 이유로 내린 결정이라고 언급했습니다. 이처럼 일부 프레임워크와 라이브러리에서 TypeScript를 선택적으로 만들거나 제거하는 움직임이 보이고 있어요.
JSDoc이라는 대안
TypeScript의 대안으로 자주 언급되는 것이 바로 JSDoc입니다. JSDoc은 주석을 통해 타입 정보를 제공하는 방식이에요.
/**
* @param {string} name - 사용자 이름
* @param {number} age - 사용자 나이
* @returns {Object} 사용자 객체
*/
function createUser(name, age) {
return { name, age };
}
JSDoc은 컴파일 단계 없이 타입 힌트를 제공할 수 있다는 장점이 있습니다. 하지만 TypeScript만큼의 강력한 타입 체크나 IDE 지원을 제공하지는 못해요. 많은 개발자들이 "JSDoc을 쓸 바에야 그냥 TypeScript를 쓰는 게 낫다"는 의견을 내놓고 있습니다.
JavaScript와 TypeScript의 미래
ECMAScript의 Type Annotations 제안
흥미롭게도 ECMAScript TC39 위원회에서는 JavaScript에 직접 타입 주석(Type Annotations)을 추가하는 제안을 검토하고 있습니다. 현재 Stage 1 단계에 있는 이 제안이 통과되면, JavaScript 자체에서 타입을 표현할 수 있게 돼요.
// 미래의 JavaScript?
function add(a: number, b: number): number {
return a + b;
}
중요한 점은 이 타입 주석들이 런타임에는 무시된다는 것입니다. 즉, 브라우저가 직접 실행할 수 있는 형태가 되는 거죠. 이렇게 되면 TypeScript의 컴파일 단계 없이도 타입 안정성을 확보할 수 있을 것으로 기대됩니다.
공존의 가능성
Type Annotations 제안이 현실화되더라도, TypeScript가 완전히 사라지지는 않을 것으로 보입니다. TypeScript는 단순히 타입 주석 이상의 기능들을 제공하고 있거든요:
- 고급 타입 시스템: 제네릭, 유니온 타입, 인터섹션 타입 등
- 타입 추론: 명시적으로 타입을 작성하지 않아도 자동으로 타입을 파악
- 데코레이터: 메타프로그래밍 기능
- 엄격한 타입 체크: 컴파일러 옵션을 통한 세밀한 제어
JavaScript에 Type Annotations가 추가되면, TypeScript는 더 고급 기능을 필요로 하는 프로젝트를 위한 도구로 포지셔닝될 가능성이 높습니다.
프레임워크와 라이브러리의 선택
React, Vue, Angular 같은 주요 프레임워크들은 모두 TypeScript를 공식적으로 지원하고 있습니다. React 공식 문서도 TypeScript 사용을 권장하고 있죠.
// React with TypeScript
interface ButtonProps {
onClick: () => void;
children: React.ReactNode;
disabled?: boolean;
}
const Button: React.FC<ButtonProps> = ({ onClick, children, disabled = false }) => {
return (
<button onClick={onClick} disabled={disabled}>
{children}
</button>
);
};
Next.js, Remix 같은 메타 프레임워크들도 TypeScript를 일급 시민(first-class citizen)으로 취급하며, 기본 설정으로 제공하고 있어요.
이런 흐름을 보면, 적어도 당분간은 TypeScript가 주류 개발 도구로 자리를 지킬 것으로 보입니다.
프로젝트에 TypeScript가 필요한지 판단하기
TypeScript를 사용하면 좋은 경우
다음 조건 중 하나라도 해당된다면 TypeScript 도입을 진지하게 고려해보세요:
프로젝트 규모가 크거나 장기 유지보수가 예상될 때
- 10개 이상의 모듈이 상호작용하는 경우
- 1년 이상 지속적으로 개발할 프로젝트
- 레거시 코드를 리팩토링해야 하는 상황
팀 규모가 크거나 협업이 중요한 경우
- 3명 이상의 개발자가 동시에 작업
- 프론트엔드와 백엔드가 같은 타입을 공유해야 할 때
- 새로운 팀원의 온보딩이 잦은 경우
안정성과 신뢰성이 중요한 경우
- 금융, 의료 등 민감한 데이터를 다루는 서비스
- B2B 엔터프라이즈 솔루션
- 수백만 명이 사용하는 프로덕션 서비스
JavaScript로도 충분한 경우
반대로 다음 상황이라면 JavaScript만으로도 충분할 수 있어요:
프로토타입이나 빠른 실험이 필요할 때
- MVP(Minimum Viable Product) 개발
- 해커톤이나 단기 프로젝트
- 아이디어 검증 단계
소규모 프로젝트나 개인 프로젝트
- 혼자 개발하고 관리하는 프로젝트
- 간단한 랜딩 페이지나 블로그
- 학습용 토이 프로젝트
이미 JSDoc으로 충분한 타입 커버리지를 확보한 경우
- 기존 코드베이스가 잘 문서화되어 있음
- 팀이 JSDoc 사용에 익숙함
- TypeScript 마이그레이션 비용이 부담스러움
하이브리드 접근법
꼭 0 아니면 100의 선택을 할 필요는 없습니다. 다음과 같은 전략도 고려해볼 수 있어요:
점진적 도입
- 새로운 모듈부터 TypeScript로 작성
- 중요한 핵심 로직부터 타입 추가
- allowJs 옵션으로 JavaScript와 TypeScript 혼용
선택적 사용
- API 인터페이스와 데이터 모델만 TypeScript로 정의
- 유틸리티 함수는 JavaScript로 유지
- 프레임워크에서 요구하는 부분만 타입 추가
타입스크립트는 도구일 뿐입니다
TypeScript 논쟁의 핵심은 "옳고 그름"이 아닙니다. DHH처럼 JavaScript의 단순함과 자유로움을 선호할 수도 있고, 대규모 프로젝트에서 TypeScript의 안정성을 중요하게 여길 수도 있어요.
중요한 건 여러분의 프로젝트 상황, 팀의 역량, 비즈니스 요구사항을 종합적으로 고려해서 결정하는 것입니다. TypeScript는 만능 해결책이 아니며, JavaScript도 구시대의 유물이 아닙니다.
ECMAScript의 Type Annotations 제안이 진행되면서, 앞으로 JavaScript와 TypeScript의 경계는 더욱 흐려질 것으로 보입니다. 그 사이 어딘가에서 여러분의 프로젝트에 맞는 최적점을 찾으시길 바랍니다.
결국 우리의 목표는 더 나은 소프트웨어를 만드는 것이니까요 :)