구조적 타이핑(Structural Typing)은 타입의 이름이 아니라 모양(가진 속성과 그 타입)이 맞으면 호환된다고 보는 타입 시스템이다. TypeScript가 이 방식을 쓴다. Java처럼 선언된 이름과 상속 관계로 판단하는 방식은 명목적 타이핑(Nominal Typing)이라 한다.
interface Point { x: number; y: number }
const p = { x: 1, y: 2, label: 'a' }
const q: Point = p // ✅ 필요한 x, y가 있으니 호환
type UserId = string
type OrderId = string
const id: UserId = 'o-1' as OrderId // ✅ 둘 다 string이라 구분되지 않음- "오리처럼 걷고 꽥꽥거리면 오리"라는 덕 타이핑(Duck Typing)을 컴파일 타임에 하는 셈이다
- 장점: 인터페이스를 미리
implements하지 않아도 모양만 맞으면 끼워 넣을 수 있어 유연하다. 테스트 대역을 만들기도 쉽다 - 단점: 의미가 다른 값(사용자 ID와 주문 ID, 미터와 킬로미터)이 같은 원시 타입이면 섞여도 모른다. 이 구멍은 타입 브랜딩으로 막는다(기본형 집착과 같은 문제)
- 변수에 담은 객체는 남는 속성이 있어도 통과하지만, 객체 리터럴을 바로 넣으면 초과 속성 검사로 잡힌다(타입 추론과 타입 검사)
- 함수 타입끼리의 호환 규칙은 공변성과 반공변성에서 다룬다