Published on

Effective TypeScript item4

✅ Item 4: 구조적 타이핑에 익숙해지기


1️⃣ 자바스크립트는 본질적으로 덕 타이핑(Duck Typing) 기반

→ 객체가 특정 **형태(shape)**를 갖추고 있으면, 그 타입처럼 취급함.

const person = {
  name: 'Boohi',
  age: 30,
};

function greet(p) {
  console.log(`Hello, ${p.name}`);
}

greet(person); // ✅ 속성 구조가 맞기 때문에 문제 없이 동작

➡ JavaScript는 명시적 타입 선언이 없어도, 속성만 맞으면 작동함.


2️⃣ TypeScript는 이 JS의 유연함을 반영해 구조적 타이핑을 채택

🔸 구조적 타이핑 (Structural Typing)

  • 객체의 속성과 형태에 따라 타입을 판단함
  • 타입 이름이나 선언 위치는 중요하지 않음
type Person = { name: string };

const user = { name: 'Boohi', age: 30 };

const p: Person = user; // ✅ age가 추가로 있어도 name 속성만 맞으면 OK

➡ 속성 “구조”만 맞으면 타입 호환 가능 → 구조적 타이핑


3️⃣ 🔁 비교: 명목적 타이핑 (Nominal Typing) vs 구조적 타이핑

구분구조적 타이핑 (TS, Go 등)명목적 타이핑 (Java, C# 등)
기준형태(shape)이름(name) 또는 선언 위치
예시{ name: string }이면 OKPerson 타입이어야만 OK
장점유연성, 간결함안전성, 의도 명확
단점과도한 호환 허용 가능성반복 선언, 명시성 요구

4️⃣ 예시 코드로 비교 이해하기

✅ 구조적 타이핑 예시 (TS)

type Point2D = { x: number; y: number };

const point3D = { x: 1, y: 2, z: 3 };

function draw(p: Point2D) {
  console.log(p.x, p.y);
}

draw(point3D); // ✅ z 속성이 있어도 구조가 맞으면 통과

point3DPoint2D보다 속성이 더 많지만, 필수 속성을 만족하므로 호환됨


❌ 명목적 타이핑이라면 (Java 스타일)

class Point2D {
  int x;
  int y;
}

class Point3D extends Point2D {
  int z;
}

Point2D p = new Point3D(); // ✅ 명시적으로 상속해야만 가능

➡ 구조가 같아도 타입 이름이 다르면 호환되지 않음


5️⃣ 구조적 타이핑의 주의점

⚠️ 의도치 않은 타입 호환을 허용할 수 있음

type Email = { value: string };
type Username = { value: string };

function send(email: Email) {
  console.log(`Sending to ${email.value}`);
}

const username: Username = { value: 'boohi' };
send(username); // ❌ 타입이 다르지만 구조가 같아서 통과됨

➡ 이처럼 "의미는 다르지만 구조가 같은 타입" 간의 허용이 버그를 유발할 수 있음

이를 해결하기 위해 “브랜디드 타입(Branded Type)” 패턴을 사용하는 경우도 있음


💡 요약 정리

핵심 개념설명
덕 타이핑JS는 구조가 맞으면 타입처럼 취급
구조적 타이핑TS는 객체의 형태(shape)에 따라 타입 호환 판단
명목적 타이핑과 차이이름 기반이 아니라 구조 기반
장점유연하고 간단한 타입 선언 가능
단점의도치 않은 호환이 허용될 수 있음
대응 전략브랜디드 타입 등으로 의미 분리 필요

✅ 결론

TypeScript는 JavaScript의 유연한 동적 특성을 따르기 위해 구조적 타이핑을 사용합니다.