타입스크립트 기초 강좌 #1 시작과 셋업

17 분 소요

이 시리즈는 자바스크립트는 어느 정도 알지만 타입스크립트는 처음인 분들을 위한 입문 강좌입니다. 7편으로 구성됩니다.

  • #1 시작과 셋업 ← 이번 글
  • #2 기본 타입
  • #3 interface와 type alias
  • #4 Union / Literal / Narrowing
  • #5 함수 타입
  • #6 제네릭 깊이
  • #7 유틸리티 타입과 tsconfig

이번 글은 "왜 타입스크립트인가"를 명확히 하고, 첫 코드를 작성해 컴파일하고 실행하는 곳까지 갑니다.

타입스크립트가 뭔가요?

**타입스크립트(TypeScript)**는 자바스크립트에 타입 시스템을 더한 언어입니다. 마이크로소프트가 2012년에 만들었고, 지금은 자바스크립트 기반 프로젝트의 사실상 표준이 됐어요. React/Vue/Node.js 큰 프로젝트는 거의 다 TypeScript로 작성됩니다.

핵심을 한 줄로 정리하면:

자바스크립트 + 타입 어노테이션 = 타입스크립트

자바스크립트로 쓸 수 있는 모든 코드는 타입스크립트로도 동작합니다. 타입스크립트는 그 위에 "이 변수는 문자열", "이 함수는 숫자를 받고 boolean을 반환" 같은 정보를 표시할 수 있는 문법을 더한 거예요.

왜 타입을 명시하나요?

자바스크립트는 동적 타입 언어라 변수가 어떤 타입인지 코드를 실행해봐야 알 수 있습니다. 작은 프로그램에서는 큰 문제가 아니지만, 코드가 커지면 다음과 같은 일이 자주 일어납니다.

동적 타입의 함정
function getDiscount(price, percent) {
  return price * percent / 100;
}
 
getDiscount(1000, 10);     // 100 — 정상
getDiscount('1000', 10);   // 1000... 어? 문자열이 들어왔는데 동작은 함
getDiscount(1000, '10');   // 100 — 동작은 하지만 의도였나?
getDiscount(1000);         // NaN — percent가 undefined

자바스크립트는 알아서 타입을 변환하거나 undefined로 채워서 코드를 일단 실행해버립니다. 버그가 한참 뒤에 가서야 드러나죠.

타입스크립트는 같은 함수에 타입을 명시하면 코드를 작성하는 시점에 잘못된 호출을 잡아냅니다.

타입스크립트 버전
function getDiscount(price: number, percent: number): number {
  return price * percent / 100;
}
 
getDiscount(1000, 10);     // ✓ OK
getDiscount('1000', 10);   // ✗ 에러: '1000'은 number가 아닙니다
getDiscount(1000, '10');   // ✗ 에러
getDiscount(1000);         // ✗ 에러: 인자가 부족합니다

에러가 컴파일 시점에 나타납니다. 실행 전에 에디터에 빨간 줄이 그어지고, 빌드도 막혀요. 버그가 사용자에게 도달하기 전에 잡힙니다.

타입스크립트의 가치 한 줄 정리

  • 에디터 자동완성/추론 — 객체의 어떤 속성이 있는지, 함수가 뭘 반환하는지 IDE가 정확히 알려줌
  • 리팩터링 안전 — 함수 시그니처 바꾸면 호출하는 모든 곳이 빨간 줄로 표시됨
  • 문서 역할 — 타입이 곧 함수의 사용법 설명서
  • 버그 사전 차단undefined/null 같은 흔한 함정을 컴파일이 막아줌

작은 토이 프로젝트에서는 부담스럽지만, 여러 명이 함께 만지거나 시간이 지나서 다시 봐야 하는 코드라면 타입스크립트의 가치가 크게 빛납니다.

타입스크립트 vs 자바스크립트 — 실행 모델

여기서 중요한 사실 — 브라우저와 Node.js는 타입스크립트를 직접 실행하지 못합니다. 타입 어노테이션 같은 문법을 모르거든요.

그래서 우리가 작성한 .ts 파일은 실행 전에 **자바스크립트로 변환(컴파일/트랜스파일)**되어야 합니다. 이 변환을 해주는 도구가 tsc (TypeScript Compiler)나 esbuild, swc, Vite 같은 빌드 도구들입니다.

실행 흐름
.ts 파일 (작성)
   ↓ (컴파일)
.js 파일 (실행 가능)

브라우저 / Node.js

흥미로운 점 — 컴파일 결과의 .js 파일에는 타입 정보가 모두 사라져 있습니다. 타입은 개발 시점에만 의미가 있고, 실행 시에는 그냥 자바스크립트인 거예요. 그래서 타입스크립트는 "런타임 추가 비용 없이 개발 시점 안전성을 얻는" 도구입니다.

첫 셋업 — 가장 단순한 방법

여러 셋업 방법이 있는데, 처음에는 가장 단순한 두 가지를 권합니다.

방법 1. tsc 직접 사용 (학습용)

순수하게 TypeScript 자체를 익히기에 최적입니다.

새 폴더 만들기
mkdir ts-learn
cd ts-learn
npm init -y
npm install --save-dev typescript
npx tsc --init

각 명령의 역할:

  • npm init -ypackage.json 생성 (Node.js 프로젝트로 만듦)
  • npm install --save-dev typescript — TypeScript 컴파일러 설치
  • npx tsc --init — 기본 tsconfig.json 파일 생성

tsconfig.json은 컴파일 옵션을 모아둔 파일입니다. 자세한 옵션은 #7에서 다루고, 지금은 만들어진 그대로 두면 됩니다.

방법 2. Vite로 빠르게 (실전 가까움)

웹 개발 맥락이라면 Vite가 컴파일 + 개발 서버까지 한 번에 처리해줘 편합니다.

Vite + TS 프로젝트
npm create vite@latest ts-learn
# Framework: Vanilla
# Variant: TypeScript
cd ts-learn
npm install
npm run dev

이 시리즈는 방법 1로 진행합니다. tsc로 직접 컴파일해보면 타입스크립트가 무엇을 하는지 가장 명확하게 이해되거든요. 나중에 Vite/Webpack으로 옮겨가도 같은 원리입니다.

첫 코드

ts-learn/ 폴더에 index.ts 파일을 만듭니다.

index.ts
function greet(name: string): string {
  return `안녕하세요, ${name}님!`;
}
 
const message: string = greet('철수');
console.log(message);

타입스크립트만의 새 문법은 두 곳입니다.

  • name: stringname이 문자열 타입임을 명시
  • (): string — 함수가 문자열을 반환함을 명시
  • const message: string = ... — 변수 message가 문자열임을 명시

컴파일하고 실행하기

컴파일
npx tsc

명령을 실행하면 같은 폴더에 index.js 파일이 만들어집니다 (tsconfig.json의 기본값에 따라 다른 위치일 수도). 그 파일을 열어보세요.

컴파일 결과 index.js
function greet(name) {
    return "안녕하세요, ".concat(name, "님!");
}
var message = greet('철수');
console.log(message);

타입 어노테이션(: string)이 모두 사라졌습니다. 그리고 ES6 문법(const, 템플릿 리터럴)이 좀 더 옛 자바스크립트로 변환된 게 보일 거예요 (구형 브라우저 지원을 위한 기본 동작 — tsconfig.jsontarget 옵션으로 조정 가능, #7에서).

이걸 Node로 실행해봅시다.

실행
node index.js
출력
안녕하세요, 철수님!

실수해보기 — 타입 에러 직접 보기

타입스크립트의 가치를 체감하려면 직접 실수를 해보는 게 가장 빠릅니다. index.ts를 다음과 같이 바꿔보세요.

index.ts (실수 버전)
function greet(name: string): string {
  return `안녕하세요, ${name}님!`;
}
 
const message: string = greet(42);  // 🚫 숫자를 넣음
console.log(message);

npx tsc를 다시 실행하면:

컴파일 에러
index.ts:5:33 - error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
 
5 const message: string = greet(42);
                                ~~
 
Found 1 error in index.ts:5

타입스크립트가 5번 줄 33번째 글자에 문제가 있다고 정확히 짚어줍니다. .js 파일도 만들어지지 않습니다 (기본 설정에서 — 옵션으로 조정 가능). 잘못된 코드가 실행 단계까지 흘러가는 걸 막아주는 거예요.

VSCode 같은 에디터에서는 npx tsc를 실행하기도 전에 빨간 줄로 즉시 표시됩니다. 작성하는 동안 실시간으로 잘못을 알려주는 셈이죠.

자동 추론 — 타입을 안 적어도 알아서 알아냄

모든 변수에 타입을 명시할 필요는 없습니다. 타입스크립트는 똑똑하게 추론해줍니다.

자동 추론
const age = 30;             // age: number 로 자동 추론
const name = '철수';         // name: string
const isAdmin = true;       // isAdmin: boolean
const items = [1, 2, 3];    // items: number[]
 
age = 'hello';              // 🚫 에러: number에 string 못 넣음

const age = 30이라고 쓰면 타입스크립트가 자동으로 age: number로 추론합니다. 그 후 age = 'hello'처럼 다른 타입을 넣으려 하면 잡아주죠.

명시적 타입 어노테이션은 다음 경우에 주로 사용합니다.

  • 함수의 매개변수와 반환 타입 (자동 추론이 약함)
  • 명확한 의도 표현 (const id: string = computeId() 같이 가독성 위해)
  • 빈 변수에 타입만 미리 선언 (let user: User | null = null)

지금부터의 글들에서 이 균형 감각이 차차 잡힐 거예요.

watch 모드 — 매번 컴파일 안 하기

매번 npx tsc를 치는 게 번거로우면 watch 모드가 있습니다.

자동 재컴파일
npx tsc --watch

파일을 수정할 때마다 자동으로 컴파일되어 즉시 결과를 받아볼 수 있어요. 학습 중에는 이 모드를 켜두는 게 편합니다.

흔한 함정과 미신

"타입스크립트는 어렵다"

처음 며칠은 어색하지만 1~2주만 써보면 자바스크립트로 돌아갈 때 오히려 불안할 정도가 됩니다. 자동완성 / 리팩터링 / 즉각적인 에러 피드백의 가치가 크거든요.

"타입스크립트는 느리다"

실행은 자바스크립트와 동일합니다 (런타임 비용 0). 컴파일 시간이 추가되긴 하지만 incremental 빌드로 거의 체감 안 됩니다.

"any를 쓰면 되잖아?"

any는 타입 시스템을 사실상 끄는 탈출구입니다. 너무 자주 쓰면 타입스크립트의 가치를 잃어요. 가끔 필요할 때만 쓰고, 보통은 더 정확한 타입을 찾아보는 게 좋습니다 (#4의 union 타입 등).

"JSDoc으로도 비슷한 효과를 낼 수 있다"

맞습니다. JSDoc 주석으로 타입을 일부 표현할 수 있어요. 다만 표현력과 도구 지원에서 TypeScript가 압도적으로 강력합니다.

마무리

이번 글에서 다룬 것들을 정리하면:

  • 타입스크립트 = 자바스크립트 + 타입 어노테이션
  • 컴파일 시점에 타입 오류를 잡고, 실행 시점엔 평범한 자바스크립트
  • npx tsc로 컴파일, watch 모드로 자동 재컴파일
  • 타입 어노테이션은 함수 시그니처에 우선 명시, 변수는 추론에 맡길 때가 많음
  • 직접 잘못된 코드를 써보고 컴파일 에러를 받아보는 게 가장 좋은 학습

다음 글인 "타입스크립트 기초 강좌 #2 기본 타입"에서는 string/number/boolean부터 시작해 array, tuple, object, enum까지 — 매일 쓰게 될 기본 타입들을 차근차근 살펴보겠습니다.