실행 전에 코드 작성 단계에서 타입 에러를 미리 잡아주는 언어.
브라우저는 TS를 직접 실행할 수 없으므로, tsc 명령으로 컴파일해 .js 파일로 변환 후 사용한다.
// 예시
tsc app.ts
// 기본 타입 → 변수명 : 타입 = 값;
const name: string = "홍길동";
const age: number = 20;
const subjects: string[] = ["국어", "영어", "수학"];
// Union → | 로 두 가지 이상 허용
// 변수에 string 타입의 값을 할당하고, 추후 number 값을 할당할 수 있음
let userId: string | number = 'id-123';
userId = 123;
// Optional → ? 로 값이 없어도 가능
let nickname?: string;
// Literal 타입 → 정해진 값만 허용
let color: 'red' | 'blue' | 'black' = 'blue';
color = 'pink'; // Error: 'pink'는 허용되지 않음
자주 쓰는 타입 조합에 이름을 붙여 재사용한다.
// 1. type 키워드로 이름 정의
type Color = 'red' | 'blue' | 'black';
// 2. 정의한 이름으로 해당 타입 사용 가능
let color: Color = 'red';
객체가 가져야 할 프로퍼티를 정의한다. (객체의 설계도)
interface Employee {
id: number;
name: string;
department: string;
}
Interface는 타입 검사 전용 도구다. JavaScript에는 "interface"라는 개념이 없기 때문에, TypeScript 컴파일러가 타입 검사를 마치면 JS로 변환될 때 완전히 제거된다. 런타임에 어떤 흔적도 남기지 않아 번들 크기에도 영향을 주지 않는다.
// TypeScript (.ts)
interface Employee {
id: number;
name: string;
}
const emp: Employee = { id: 1, name: "김철수" };
// 컴파일 결과 (.js) — interface 흔적 없음
const emp = { id: 1, name: "김철수" };
Interface vs Class
Interface는 설계도만 정의하고, Class는 실제 동작하는 코드를 만든다.
implements키워드로 클래스가 인터페이스를 따르도록 강제할 수 있다.
public / private / readonly 로 각 프로퍼티의 접근 범위를 제한한다.
class Employee {
public name: string; // 어디서든 접근 가능 (기본값)
private salary: number; // 클래스 내부에서만 접근 가능
readonly id: number; // 읽기 전용 — 초기화 후 변경 불가
// 생성자 매개변수에 접근 제어자를 쓰면 선언 + 할당 동시에
constructor(
public department: string,
name: string,
salary: number,
id: number
) {
this.name = name;
this.salary = salary;
this.id = id;
}
// private 값은 getter 메서드로만 노출
getSalary(): number {
return this.salary;
}
}
const emp = new Employee("개발팀", "이영희", 5000, 1);
emp.name; // OK — public
emp.department; // OK — public (생성자 단축 선언)
emp.getSalary(); // OK — 5000
emp.salary; // Error: private 프로퍼티
emp.id = 99; // Error: readonly 프로퍼티
T는 어떤 타입이든 넣을 수 있는 '빈 박스'와 같다.
함수나 인터페이스를 정의할 때 타입을 미리 지정하지 않고, 실제로 사용할 때 타입을 결정하여 코드의 재사용성을 높인다.
function identity<T>(value: T): T {
return value;
}
identity<string>("hello"); // T = string
identity<number>(42); // T = number
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
interface User { id: number; name: string; }
interface Post { title: string; body: string; }
// 같은 구조, 다른 data 타입
const userRes: ApiResponse<User> = {
data: { id: 1, name: "박민준" },
status: 200,
message: "ok",
};
const postRes: ApiResponse<Post> = {
data: { title: "TypeScript 입문", body: "..." },
status: 200,
message: "ok",
};
| 종류 | 표기법 | 예시 |
|---|---|---|
| 기본 내장 타입 | 소문자 | string, number, boolean |
| type alias | PascalCase | Status, Subject, UserId |
| interface | PascalCase | UserInfo, ApiResponse |
01. TypeScript는 JavaScript에 안전망을 씌운 것
런타임 에러를 작성 단계에서 발견하면 디버깅 시간이 크게 줄어든다.
02. 팀 프로젝트에서 빛을 발한다
타입 선언은 처음엔 번거롭게 느껴지지만, 팀 프로젝트에서 코드를 처음 보는 사람도 타입만 보면 의도를 파악할 수 있다. 결국 타입이 곧 문서다.