TypeScriptTypeScript 기초강의 8개 중 3번째난이도 기초

인터페이스와 타입 별칭 — 복잡한 구조 정의하기

발행 읽는 시간 약 1 분

  • TypeScript
  • interface
  • type
  • 유니온
  • 인터섹션

강의 소개

interface와 type alias로 객체 구조를 정의하는 방법을 배웁니다. 선택적 속성, 읽기 전용, 확장, 유니온·인터섹션 타입도 함께 익힙니다.

인터페이스 (Interface)#

객체의 구조(형태)를 정의합니다.

TypeScript
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: "영희",
};

선택적 속성과 읽기 전용#

TypeScript
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();  // ❌ 읽기 전용

인터페이스 확장#

TypeScript
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 키워드로 타입에 이름을 붙입니다.

TypeScript
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: 차이점#

TypeScript
// 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)#

여러 타입 중 하나를 허용합니다.

TypeScript
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)#

여러 타입을 모두 만족해야 합니다.

TypeScript
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(),
};

인덱스 시그니처#

동적 키를 가진 객체 타입을 정의합니다.

TypeScript
interface StringMap {
    [key: string]: string;
}

const translations: StringMap = {
    hello: "안녕",
    bye: "안녕히",
    thanks: "감사합니다",
};

// 특정 키와 인덱스 시그니처 혼합
interface Config {
    mode: "dev" | "prod";       // 고정 키
    [key: string]: unknown;     // 나머지 동적 키
}

정리#

개념문법특징
interfaceinterface Foo { }선언 병합, 확장 (extends)
type aliastype Foo = { }유니온·인터섹션·원시 타입 가능
선택적 속성prop?: Type있어도 없어도 됨
읽기 전용readonly prop: Type할당 후 변경 불가
유니온A | BA 또는 B
인터섹션A & BA와 B 모두

다음 편에서는 함수와 제네릭 — 재사용 가능한 타입 안전 함수를 만드는 방법을 배웁니다.

Follow · Ask · Work

이 글이 도움이 됐다면

짧은 작업 기록과 데모는 인스타그램에 올립니다. 만들고 싶은 것이 있다면 프로젝트 의뢰나 협업 제안도 편하게 보내 주세요.

글쓴이

파란여우

직접 만든 AI 앱·제품의 개발·배포를 공개하는 실전형 테크 크리에이터

파란여우 소개 Instagram @bluefox._.hi

이어서 보기

만들고 싶은 것이 있다면 프로젝트 의뢰로 알려 주세요.