iBetter Books
수정

이 책에서 배운 것

첫 페이지를 펼쳤던 날을 기억하나요?

let name: string = "Alice" 라는 코드를 보고 "왜 굳이 string을 써야 하지?"라고 생각했을 겁니다. JavaScript에서는 그냥 let name = "Alice"라고 써도 잘 돌아가니까요.

그런데 지금은 다릅니다. 타입을 쓰지 않으면 오히려 불안한 느낌이 드는 경험, 조금씩 생기고 있지 않나요? 그것이 바로 TypeScript적 사고방식이 몸에 배기 시작한 신호입니다.

이 챕터에서는 PART 01부터 08까지 여정을 되돌아봅니다.


PART 01 — 개발 환경 준비하기

TypeScript는 브라우저나 Node.js가 직접 이해하지 못합니다. 작성한 코드는 반드시 JavaScript로 변환(컴파일)되어야 합니다.

이 파트에서는 Node.js와 TypeScript 컴파일러를 설치하고, tsconfig.json으로 컴파일러에게 지시사항을 전달하는 방법을 익혔습니다. 터미널에서 tsc를 처음 실행했을 때의 그 감각, 기억하시나요?

핵심 개념.

  • npm install -g typescript로 컴파일러 설치
  • tsconfig.jsontarget, strict 설정
  • tsc --watch로 자동 컴파일

PART 02 — 첫 번째 타입

TypeScript의 타입 시스템을 처음 만났습니다.

string, number, boolean이라는 원시 타입부터 시작해서, 배열과 튜플, anyunknown의 차이, 그리고 TypeScript가 값만 보고도 타입을 추론하는 능력까지 살펴봤습니다.

핵심 개념.

  • 원시 타입 string, number, boolean
  • 배열 string[], 튜플 [string, number]
  • any(타입 검사 포기) vs unknown(안전한 미지 타입)
  • 타입 추론 — 직접 쓰지 않아도 TypeScript가 알아서 파악

PART 03 — 타입으로 생각하기

단순한 값 하나가 아니라, 데이터의 모양(shape)을 정의하는 방법을 익혔습니다.

interfacetype으로 객체 구조를 설계하고, |(유니언)과 &(인터섹션)으로 타입을 조합했습니다. 리터럴 타입으로 "이 값만 허용"이라는 정밀한 제약도 표현해봤습니다.

핵심 개념.

  • interfacetype alias로 객체 형태 정의
  • 유니언 타입 A | B — 이것 또는 저것
  • 인터섹션 타입 A & B — 이것이면서 저것
  • 리터럴 타입 "pending" | "done" — 특정 값만 허용

PART 04 — 함수에 타입 입히기

함수는 TypeScript에서 가장 많이 쓰이는 구조입니다.

매개변수 타입, 반환 타입, 선택적 매개변수, 기본값, 오버로드까지 함수에 타입을 입히는 다양한 방법을 배웠습니다. 화살표 함수의 타입 표기 방식도 자연스러워졌을 겁니다.

핵심 개념.

  • 매개변수와 반환 타입 명시 (name: string): string
  • 선택적 매개변수 age?: number
  • 기본값 매개변수 role = "user"
  • 함수 타입 표현식 (a: number, b: number) => number
  • 함수 오버로드 — 같은 이름, 다른 시그니처

PART 05 — 타입 좁히기

TypeScript의 정적 분석이 실제로 얼마나 똑똑한지 느꼈던 파트입니다.

typeof, instanceof, in 연산자로 분기 안에서 타입을 좁히고, 사용자 정의 타입 가드로 커스텀 검사 함수를 만들었습니다. 판별 유니언으로 여러 상태를 안전하게 다루는 패턴도 익혔습니다.

핵심 개념.

  • typeof 가드 — if (typeof x === "string")
  • instanceof 가드 — 클래스 인스턴스 확인
  • in 가드 — 객체에 특정 속성이 있는지 확인
  • 사용자 정의 타입 가드 x is SomeType
  • 판별 유니언 kind 필드로 타입 분기

PART 06 — 제네릭 — 타입의 함수

TypeScript를 "그냥 타입 붙이는 도구"에서 "재사용 가능한 타입 설계 도구"로 격상시키는 개념을 배웠습니다.

제네릭은 타입 자체를 매개변수처럼 받습니다. Array<T>, Promise<T>처럼 이미 익숙한 것들도 모두 제네릭이었습니다. 직접 제네릭 함수와 인터페이스를 만들고, extends로 타입 제약을 두는 방법도 익혔습니다.

핵심 개념.

  • 제네릭 함수 function identity<T>(value: T): T
  • 제네릭 인터페이스 interface Box<T>
  • 타입 제약 T extends string | number
  • 유틸리티 타입 Partial<T>, Required<T>, Readonly<T>, Pick<T, K>, Omit<T, K>

PART 07 — 모듈과 프로젝트 구조

코드를 파일 단위로 나누고 연결하는 방법을 익혔습니다.

exportimport로 타입과 값을 공유하고, 경로 별칭으로 깔끔한 import 경로를 만들었습니다.

핵심 개념.

  • export / import 타입과 값 공유
  • export type — 타입만 내보내기
  • tsconfig.json paths로 경로 별칭 설정

PART 08 — 미니 프로젝트 — 퀴즈 앱 만들기

배운 것들을 한데 모아 실제 동작하는 앱을 완성했습니다.

퀴즈 데이터를 인터페이스로 모델링하고, 상태를 판별 유니언으로 표현하고, 제네릭 유틸리티 함수로 로직을 정리하고, 모듈로 파일을 분리했습니다. 코드 한 줄 한 줄에 지금까지 배운 개념이 담겨 있습니다.

핵심 개념.

  • 도메인 모델 설계 (Question, QuizState)
  • 판별 유니언으로 상태 관리
  • 제네릭 함수로 재사용 가능한 로직 작성
  • 모듈 분리로 코드 구조화

TypeScript적 사고방식

지금까지 배운 내용을 기술 목록으로만 보면 안 됩니다. 그보다 더 중요한 것은 사고방식의 변화입니다.

TypeScript를 배우기 전에는 이렇게 생각했을 겁니다.

"일단 코드부터 짜고, 오류가 나면 고치면 되지."

TypeScript를 배운 후에는 이렇게 생각하게 됩니다.

"이 함수에 어떤 값이 들어올 수 있지? 어떤 값을 돌려줘야 하지? 이 상태는 어떤 모양이어야 하지?"

코드를 작성하기 전에 데이터의 형태를 먼저 설계하는 것. 그것이 TypeScript적 사고방식의 핵심입니다.

이 습관은 TypeScript를 쓰지 않는 상황에서도 코드를 더 명확하게 만드는 데 도움이 됩니다. TypeScript는 단순한 도구가 아니라, 더 나은 개발자가 되는 훈련이기도 합니다.


지금 여러분이 할 수 있는 것

이 책을 마친 지금, 여러분은 다음을 할 수 있습니다.

  • TypeScript 프로젝트를 새로 만들고 설정할 수 있다.
  • 객체, 배열, 함수에 적절한 타입을 붙일 수 있다.
  • 유니언 타입과 타입 좁히기로 다양한 상태를 안전하게 다룰 수 있다.
  • 제네릭으로 재사용 가능한 타입을 설계할 수 있다.
  • 모듈로 코드를 구조화할 수 있다.
  • 작은 규모의 TypeScript 프로젝트를 처음부터 완성할 수 있다.

작은 것처럼 보일 수 있지만, 이것은 실무 TypeScript의 80%를 커버합니다. 나머지 20%는 다음 단계에서 만납니다.