타입스크립트 기초 강좌 #1 시작과 셋업
이 시리즈는 자바스크립트는 어느 정도 알지만 타입스크립트는 처음인 분들을 위한 입문 강좌입니다. 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 -y—package.json생성 (Node.js 프로젝트로 만듦)npm install --save-dev typescript— TypeScript 컴파일러 설치npx tsc --init— 기본tsconfig.json파일 생성
tsconfig.json은 컴파일 옵션을 모아둔 파일입니다. 자세한 옵션은 #7에서 다루고, 지금은 만들어진 그대로 두면 됩니다.
방법 2. Vite로 빠르게 (실전 가까움)
웹 개발 맥락이라면 Vite가 컴파일 + 개발 서버까지 한 번에 처리해줘 편합니다.
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 파일을 만듭니다.
function greet(name: string): string {
return `안녕하세요, ${name}님!`;
}
const message: string = greet('철수');
console.log(message);타입스크립트만의 새 문법은 두 곳입니다.
name: string—name이 문자열 타입임을 명시(): string— 함수가 문자열을 반환함을 명시const message: string = ...— 변수message가 문자열임을 명시
컴파일하고 실행하기
npx tsc명령을 실행하면 같은 폴더에 index.js 파일이 만들어집니다 (tsconfig.json의 기본값에 따라 다른 위치일 수도). 그 파일을 열어보세요.
function greet(name) {
return "안녕하세요, ".concat(name, "님!");
}
var message = greet('철수');
console.log(message);타입 어노테이션(: string)이 모두 사라졌습니다. 그리고 ES6 문법(const, 템플릿 리터럴)이 좀 더 옛 자바스크립트로 변환된 게 보일 거예요 (구형 브라우저 지원을 위한 기본 동작 — tsconfig.json의 target 옵션으로 조정 가능, #7에서).
이걸 Node로 실행해봅시다.
node index.js안녕하세요, 철수님!실수해보기 — 타입 에러 직접 보기
타입스크립트의 가치를 체감하려면 직접 실수를 해보는 게 가장 빠릅니다. 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까지 — 매일 쓰게 될 기본 타입들을 차근차근 살펴보겠습니다.