인터페이스 (Interface)
객체의 구조(형태)를 정의합니다.
interface User {
id: number;
name: string;
email: string;
}
const user: User = {
id: 1,
name: "철수",
email: "kim@example.com",
};
// ❌ 오류: email 누락
const user2: User = {
id: 2,
name: "영희",
};
선택적 속성과 읽기 전용
interface UserProfile {
id: number;
name: string;
email?: string; // 선택적 (optional)
readonly createdAt: Date; // 읽기 전용
bio?: string;
}
const profile: UserProfile = {
id: 1,
name: "철수",
createdAt: new Date(),
};
profile.name = "영희"; // ✅
// profile.createdAt = new Date(); // ❌ 읽기 전용
인터페이스 확장
interface Animal {
name: string;
age: number;
}
interface Dog extends Animal {
breed: string;
speak(): string;
}
const dog: Dog = {
name: "바둑이",
age: 3,
breed: "진돗개",
speak: () => "멍멍!",
};
// 여러 인터페이스 확장
interface Pet extends Animal, Dog {
owner: string;
}
타입 별칭 (Type Alias)
type 키워드로 타입에 이름을 붙입니다.
type ID = string | number;
type Point = { x: number; y: number };
type Callback = (error: Error | null, result: string) => void;
// 사용
const userId: ID = "user-123";
const pos: Point = { x: 10, y: 20 };
interface vs type: 차이점
// interface: 동일 이름으로 선언 병합 가능
interface Window {
title: string;
}
interface Window {
location: string; // 자동으로 병합됨
}
// type: 재선언 불가 → 명확성이 장점
type Point = { x: number };
// type Point = { y: number }; // ❌ 중복 식별자
// 확장
interface Animal { name: string }
interface Dog extends Animal { breed: string } // interface 확장
type Animal2 = { name: string };
type Dog2 = Animal2 & { breed: string }; // 인터섹션으로 확장
실무 가이드: 객체 구조는 interface, 유니온·인터섹션·원시 타입 조합은 type 사용.
유니온 타입 (Union)
여러 타입 중 하나를 허용합니다.
type StringOrNumber = string | number;
function display(value: string | number): string {
if (typeof value === "string") {
return value.toUpperCase();
}
return value.toFixed(2);
}
// 리터럴 유니온
type Direction = "north" | "south" | "east" | "west";
type StatusCode = 200 | 404 | 500;
function handleStatus(code: StatusCode): string {
if (code === 200) return "성공";
if (code === 404) return "찾을 수 없음";
return "서버 오류";
}
인터섹션 타입 (Intersection)
여러 타입을 모두 만족해야 합니다.
interface Timestamped {
createdAt: Date;
updatedAt: Date;
}
interface SoftDelete {
deletedAt?: Date;
}
type BaseEntity = Timestamped & SoftDelete;
interface User extends BaseEntity {
name: string;
email: string;
}
const user: User = {
name: "철수",
email: "kim@example.com",
createdAt: new Date(),
updatedAt: new Date(),
};
인덱스 시그니처
동적 키를 가진 객체 타입을 정의합니다.
interface StringMap {
[key: string]: string;
}
const translations: StringMap = {
hello: "안녕",
bye: "안녕히",
thanks: "감사합니다",
};
// 특정 키와 인덱스 시그니처 혼합
interface Config {
mode: "dev" | "prod"; // 고정 키
[key: string]: unknown; // 나머지 동적 키
}
정리
| 개념 | 문법 | 특징 |
|---|---|---|
| interface | interface Foo { } | 선언 병합, 확장 (extends) |
| type alias | type Foo = { } | 유니온·인터섹션·원시 타입 가능 |
| 선택적 속성 | prop?: Type | 있어도 없어도 됨 |
| 읽기 전용 | readonly prop: Type | 할당 후 변경 불가 |
| 유니온 | A | B | A 또는 B |
| 인터섹션 | A & B | A와 B 모두 |
다음 편에서는 함수와 제네릭 — 재사용 가능한 타입 안전 함수를 만드는 방법을 배웁니다.