티스토리 뷰

 

현대 웹 개발에서 자바스크립트(JavaScript)는 빼놓을 수 없는 필수 언어입니다. 하지만 프로젝트의 규모가 커질수록 자바스크립트만으로는 통제하기 힘든 '불확실성'에 직면하게 됩니다.

오늘은 자바스크립트의 태생적 한계가 무엇인지, 그리고 타입스크립트(TypeScript)가 어떻게 우리 코드에 강력한 안정성을 부여하는지 풍부한 예제와 함께 살펴보겠습니다.

1. 자바스크립트의 한계: "런타임의 공포"

자바스크립트는 동적 타입(Dynamic Typing) 언어입니다. 변수의 타입이 실행 시점(Runtime)에 결정된다는 뜻이죠. 이는 유연함을 주지만, 대규모 협업이나 복잡한 로직에서는 치명적인 실수를 유발합니다.

예제 1: 의도치 않은 타입 변환 (Implicit Coercion)

자바스크립트는 개발자의 실수를 알아서 '추측'하여 처리하려고 노력합니다. 하지만 그 결과는 황당할 때가 많습니다.

function add(a, b) {
  return a + b;
}

console.log(add(5, 10));    // 15 (정상)
console.log(add("5", 10));  // "510" (문자열 연결 - 버그 발생!)

숫자를 더하려고 만든 함수에 문자열이 들어와도 자바스크립트는 경고 한 줄 주지 않습니다. 이 값은 서비스 어딘가로 흘러가 결국 '결제 금액 오류' 같은 심각한 사고로 이어질 수 있습니다.

예제 2: "undefined is not a function"

자바스크립트 개발자가 가장 자주 마주하는 에러입니다. 객체의 구조를 잘못 파악하거나 오타가 났을 때 발생합니다.

const user = {
  name: "John",
  age: 25
};

// 프로퍼티 이름을 잘못 입력한 경우 (email 대신 mail)
console.log(user.mail.toLowerCase()); 
// Uncaught TypeError: Cannot read properties of undefined (reading 'toLowerCase')

프로그램은 이 지점에서 즉시 멈춰버립니다. 사용자는 하얀 화면만 보게 되겠죠.

2. TypeScript란 무엇인가?

타입스크립트는 자바스크립트의 **슈퍼셋(Superset)**입니다. 즉, 자바스크립트의 모든 기능을 포함하면서 그 위에 **'정적 타입 시스템'**을 얹은 언어입니다.

  • 컴파일 단계에서 에러 포착: 코드가 실행되기 전, 에러를 먼저 잡아냅니다.
  • 자바스크립트로 변환: 브라우저는 타입스크립트를 이해하지 못하므로, 최종적으로는 순수 자바스크립트로 변환(Compile)되어 실행됩니다.

3. TypeScript가 가져다주는 안정성

위의 문제들을 타입스크립트는 어떻게 해결할까요?

해결 1: 명확한 타입 정의 (Type Annotation)

함수의 매개변수와 반환 타입을 미리 정의하여 잘못된 데이터의 유입을 원천 차단합니다.

function add(a: number, b: number): number {
  return a + b;
}

add(5, 10);     // OK
add("5", 10);   // Error: 'string' 형식의 인수는 'number' 형식의 매개변수에 할당될 수 없습니다.

코드를 작성하는 즉시 에디터에서 빨간 줄로 경고를 보내줍니다. 실행해보지 않아도 버그를 알 수 있습니다.

해결 2: 인터페이스(Interface)를 통한 구조 설계

객체의 형태를 약속(Contract)으로 정의할 수 있습니다.

interface User {
  name: string;
  age: number;
  email?: string; // 선택적 프로퍼티
}

const user: User = {
  name: "Jane",
  age: 28
};

// 존재하지 않는 프로퍼티에 접근 시도
console.log(user.mail); // Error: 'User' 형식에 'mail' 속성이 없습니다.

해결 3: 강력한 자동 완성 (DX 향상)

타입스크립트는 개발 도구(VS Code 등)와 환상적인 호환성을 자랑합니다. 객체에 어떤 메서드가 있는지, 인수로 무엇을 넘겨야 하는지 일일이 기억할 필요가 없습니다.

4. 실전 예제: API 응답 처리

실제 현업에서 가장 유용한 순간은 외부 API 데이터를 처리할 때입니다.

JavaScript의 방식 (불안함)

fetch('/api/user/1')
  .then(res => res.json())
  .then(user => {
    // user에 무엇이 들어있을까? 매번 문서를 보거나 console.log를 찍어야 함
    console.log(user.profile.imageUrl); 
  });

TypeScript의 방식 (안정성)

interface ApiResponse {
  id: number;
  username: string;
  profile: {
    avatarUrl: string;
  };
}

fetch('/api/user/1')
  .then(res => res.json())
  .then((user: ApiResponse) => {
    // .을 찍는 순간 avatarUrl이 자동 완성됨!
    // 만약 imageUrl이라고 오타를 내면 즉시 에러 발생
    console.log(user.profile.avatarUrl); 
  });

5. 결론: 생산성을 위한 투자

처음에는 타입을 정의하는 과정이 번거롭고 "코드 양만 늘어나는 것 아니야?"라고 느낄 수 있습니다. 하지만 한 번 작성된 타입은 수천 번의 테스트 코드보다 강력하게 프로그램을 보호합니다.

  • 유지보수: 6개월 뒤 내가 짠 코드를 봐도 데이터 구조가 한눈에 들어옵니다.
  • 협업: 동료가 만든 함수의 타입을 확인하는 것만으로 사용법을 익힐 수 있습니다.
  • 리팩토링: 변수 이름을 바꾸거나 구조를 변경할 때, 연결된 모든 곳의 에러를 찾아줍니다.

이제는 선택이 아닌 필수인 시대. 아직 망설이고 있다면, 작은 프로젝트부터 타입스크립트를 도입해 보시는 건 어떨까요? 여러분의 '퇴근 시간'이 훨씬 앞당겨질 것입니다!

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함