노트

구조적 타이핑

Structural Typing

CS#ts · 연결된 개념 9개

쉽게 말하면

구조적 타이핑은 '콘센트 모양만 맞으면 어느 회사 플러그든 꽂힌다'는 규칙이에요. 이름표나 족보 대신 가진 속성의 모양을 보고 호환을 정하니, 미리 선언하지 않아도 끼워 쓸 수 있어요.

비유가 깨지는 곳 모양만 보니 의미가 다른 값도 섞여요. 사용자 ID와 주문 ID가 둘 다 string이면 서로 바꿔 넣어도 모르니까, 이 구멍은 타입 브랜딩으로 막아요.

구조적 타이핑(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, 미터와 킬로미터)이 같은 원시 타입이면 섞여도 모른다. 이 구멍은 타입 브랜딩으로 막는다(기본형 집착과 같은 문제)
  • 변수에 담은 객체는 남는 속성이 있어도 통과하지만, 객체 리터럴을 바로 넣으면 초과 속성 검사로 잡힌다(타입 추론과 타입 검사)
  • 함수 타입끼리의 호환 규칙은 공변성과 반공변성에서 다룬다

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • type과 interface

    type(타입 별칭, Type Alias)과 interface는 둘 다 타입에 이름을 붙이는 방법이다. 객체 모양을 정의할 때는 대부분 바꿔 써도 되지만, 확장 방식과 표현 범위가 다르다.

  • TypeScript 클래스 문법

    TypeScript는 JavaScript 클래스에 접근 제어자(Access Modifier), readonly, 추상 클래스(Abstract Class), 생성자 매개변수 프로퍼티(Parameter Properties) 같은 타입 수준 문법을 더한다. 이들은 컴파일 때 검사에만 쓰이고, 출력 JS에서는 대부분 사라진다.

  • 매핑된 타입과 keyof

    매핑된 타입(Mapped Types)은 기존 타입의 키를 하나씩 돌며 새 타입을 만드는 문법([K in keyof T]: …)이다. keyof T는 객체 타입의 키 유니언을, T[K](인덱스 접근 타입, Indexed Access Type)는 그 키의 값 타입을 꺼낸다.

  • 유니언·인터섹션·리터럴 타입

    유니언 타입(Union Type, A | B)은 "A이거나 B인 값"이고, 인터섹션 타입(Intersection Type, A & B)은 "A이면서 B인 값"이다. 리터럴 타입(Literal Type)은 'left'나 3처럼 특정 값 하나만 허용하는 타입이다.

  • 유틸리티 타입

    유틸리티 타입(Utility Types)은 기존 타입에서 새 타입을 만들어 주는 TypeScript 내장 제네릭 타입이다. 같은 모양을 손으로 다시 선언하지 않게 해 준다.

보기 옵션