어제 오늘 내일

[TypeScript] 1. JavaScript의 한계와 정적 타입이 해결하는 문제 본문

IT/TypeScript

[TypeScript] 1. JavaScript의 한계와 정적 타입이 해결하는 문제

hi.anna 2026. 8. 9. 12:41

이 글의 목표: TypeScript를 "왜" 쓰는지 체감하기. 문법을 배우기 전에, 타입이 없어서 겪는 고통부터 살펴봅니다.

 

JavaScript는 관대하다. 너무 관대하다.

JavaScript는 실행하기 전까지 아무것도 검사하지 않습니다. 아래 코드를 봅시다.

// 사용자 객체에서 할인가를 계산하는 함수
function getDiscountedPrice(product, rate) {
  return product.price - product.price * rate;
}

// 어딘가에서 이렇게 호출했다고 하자
getDiscountedPrice({ price: 10000 }, 0.1); // 9000  ✅ 정상

// 하지만 실수로 이렇게 부르면?
getDiscountedPrice({ prise: 10000 }, 0.1); // price 오타 → NaN  ❌
getDiscountedPrice(10000, 0.1);            // 숫자를 넘김 → NaN  ❌
getDiscountedPrice({ price: 10000 });      // rate 누락 → NaN    ❌

세 가지 실수 모두 에러 없이 조용히 NaN을 반환합니다. 코드는 멀쩡히 실행되고, 문제는 한참 뒤 결제 화면에서 "가격: NaN원"으로 발견됩니다.

런타임 에러 vs 컴파일 타임 에러

버그를 발견하는 시점은 빠를수록 좋습니다.

  • 런타임 에러: 코드가 실행될 때 터짐. 사용자가 특정 버튼을 눌러야만 재현될 수도 있음.
  • 컴파일 타임 에러: 코드를 작성하는 순간, 에디터에서 빨간 줄로 잡힘.

TypeScript는 위 실수들을 작성하는 순간 잡아줍니다.

// product의 구조와 rate의 타입을 명시한다
type Product = {
  price: number; // price는 반드시 number
};

function getDiscountedPrice(product: Product, rate: number): number {
  return product.price - product.price * rate;
}

getDiscountedPrice({ prise: 10000 }, 0.1);
// ❌ 에러: '{ prise: number }' 형식에 'price'가 없습니다. 'prise'는 오타입니까?

getDiscountedPrice(10000, 0.1);
// ❌ 에러: 'number' 형식은 'Product' 형식에 할당할 수 없습니다.

getDiscountedPrice({ price: 10000 });
// ❌ 에러: 인수가 2개 필요한데 1개만 전달했습니다.

세 개의 버그가 실행되기도 전에 사라졌습니다.

타입은 "살아있는 문서"다

주석은 거짓말을 할 수 있습니다. 코드가 바뀌어도 주석은 그대로 남으니까요. 하지만 타입은 컴파일러가 강제하기 때문에 항상 코드와 일치합니다.

// 이 함수가 무엇을 받고 무엇을 반환하는지, 타입만 봐도 알 수 있다
function formatUser(user: { name: string; age: number }): string {
  return `${user.name} (${user.age}세)`;
}

새 팀원이 이 함수를 쓸 때, 별도 설명 없이도 "이름(string)과 나이(number)를 가진 객체를 넣으면 문자열이 나온다"는 걸 즉시 압니다.

그리고, 에디터가 똑똑해진다

타입이 있으면 에디터가 자동완성, 리팩터링, "정의로 이동" 같은 기능을 정확하게 제공합니다.

type Order = { id: string; total: number; paid: boolean };

function process(order: Order) {
  order. // ← 여기서 . 을 찍는 순간 id, total, paid 가 자동완성으로 뜬다
}

이 자동완성은 단순한 편의가 아니라, 잘못된 속성 이름을 원천 차단하는 안전장치입니다.

그럼 단점은 없나?

있습니다. 솔직하게 짚고 갑니다.

  • 빌드 단계가 추가됩니다. .ts는 브라우저가 직접 못 읽으니 .js로 변환(컴파일)해야 합니다.
  • 초반 학습 곡선이 있습니다. 특히 제네릭, 조건부 타입 같은 고급 기능은 익숙해지는 데 시간이 걸립니다.
  • 타입을 맞추느라 오히려 코드가 길어지는 순간이 옵니다.

하지만 프로젝트가 커질수록, 팀이 커질수록 이 비용은 빠르게 회수됩니다. 혼자 만드는 100줄 스크립트라면 JS로 충분하지만, 여러 명이 수년간 유지보수할 코드베이스라면 타입의 가치는 압도적입니다.

정리

  • JavaScript는 실행 전까지 아무것도 검사하지 않아, 사소한 실수가 조용한 버그로 이어진다.
  • TypeScript는 작성하는 순간 타입 오류를 잡아 버그를 앞당겨 발견하게 한다.
  • 타입은 항상 코드와 일치하는 "살아있는 문서"이며, 에디터를 똑똑하게 만든다.
  • 빌드 단계와 학습 비용이라는 대가가 있지만, 규모가 커질수록 이득이 커진다.

다음 글에서는 실제로 TypeScript를 실행할 수 있는 개발 환경을 세팅합니다.

반응형
Comments