--- id: wiki-2026-0508-구조적-타이핑-structural-typing title: 구조적 타이핑(Structural Typing) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Structural Typing, Duck Typing (static), 구조적 타이핑] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [typescript, type-system, structural-typing, go-interface] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: TypeScript/Go framework: TS 5.x / Go 1.22+ --- # 구조적 타이핑(Structural Typing) ## 매 한 줄 > **"매 type compatibility 를 name 이 아닌 shape (members) 으로 판단하는 type system"**. 매 Go interface, TypeScript, OCaml object 가 대표적. 매 nominal 의 정반대 — 매 "if it walks like a duck" 의 static 버전. ## 매 핵심 ### 매 nominal vs structural - **Nominal** (Java, C#): 매 declared 동일 type / inheritance 만 호환. - **Structural** (TS, Go interface, OCaml): 매 같은 shape 면 호환 — 매 declaration 무관. ### 매 TS 의 작동 - 매 interface / type alias 는 매 shape 만 정의. - 매 assignment / argument 시 매 source 가 target 의 모든 required member 를 가지면 OK. - 매 extra member 는 OK (단, EPC 는 fresh literal 에서만 차단). ### 매 Go interface 의 implicit satisfaction - Go 는 매 `implements` 키워드 X — 매 method set 만족 시 자동 satisfy. ### 매 응용 1. Mock / test double 의 trivial implementation. 2. Adapter 의 boilerplate 절감. 3. Library 간 type 의 cross-compat. 4. Type-driven design — 매 minimal interface. ## 💻 패턴 ### TS structural compatibility ```typescript interface Named { name: string } class Cat { name = "Tom"; meow() {} } const x: Named = new Cat(); // ✅ Cat 이 Named 를 implements 선언 X 이지만 OK ``` ### TS interface vs nominal-like brand ```typescript // 매 nominal-style (brand) type Email = string & { __brand: "Email" }; type UserId = string & { __brand: "UserId" }; const e: Email = "a@b.com" as Email; const u: UserId = e; // ❌ brand mismatch — 매 nominal-like 차단 ``` ### Go interface 의 implicit satisfy ```go type Reader interface { Read(p []byte) (int, error) } type FileR struct{ /* ... */ } func (f *FileR) Read(p []byte) (int, error) { /* ... */ return 0, nil } var r Reader = &FileR{} // ✅ implements 선언 없음 — 매 method 매 충족 ``` ### Duck-typing function ```typescript function logName(x: { name: string }) { console.log(x.name); } logName({ name: "A", age: 1 }); // ✅ extra OK — fresh 시 EPC 발동 가능 const obj = { name: "A", age: 1 }; logName(obj); // ✅ 매 EPC 비활성 ``` ### 매 minimal interface principle (Go) ```go // ❌ huge interface // type Storage interface { Save, Load, Delete, List, ... } // ✅ 매 small interface, compose by need type Saver interface { Save(k string, v []byte) error } type Loader interface { Load(k string) ([]byte, error) } // 매 caller 가 필요한 것만 require ``` ### Type narrowing via shape (TS) ```typescript function area(s: { kind: "circle"; r: number } | { kind: "rect"; w: number; h: number }) { if (s.kind === "circle") return Math.PI * s.r * s.r; // shape narrowed return s.w * s.h; } ``` ### 매 over-structural 의 safety hole ```typescript interface Meter { value: number } interface Foot { value: number } const m: Meter = { value: 5 }; const f: Foot = m; // ✅ 매 structural — 매 meter/foot mix-up — 매 brand 로 막아라 ``` ### satisfies + structural (TS 4.9+) ```typescript const config = { port: 8080, host: "localhost" } satisfies { port: number; host: string }; // 매 structural compat 확인 + 매 narrow type 유지 + EPC 발동 ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | 매 mocking / testing | structural — 매 trivial fake | | 매 minimal coupling | minimal interface (Go style) | | 매 unit safety (Email vs UserId) | brand / nominal-emulation | | 매 cross-library | structural compat | | 매 enum / discriminator | tagged union (kind: "...") | **기본값**: 매 TS / Go 의 structural 활용 + 매 unit safety 가 필요한 곳만 brand. 매 모든 type 의 brand 의 X. ## 🔗 Graph - 부모: [[TypeScript 타입 시스템 (TypeScript Type System)|Type Systems]] - 변형: [[Nominal-Typing-in-TypeScript|Nominal Typing]] · [[Duck Typing]] - 응용: [[TypeScript]] - Adjacent: [[과잉 속성 체크 (Excess Property Checking)]] · [[Branded Type]] · [[Discriminated Union]] ## 🤖 LLM 활용 **언제**: type design review, interface 의 minimization, structural mismatch 디버깅. **언제 X**: 매 runtime type check — 매 structural 은 compile-time only. ## ❌ 안티패턴 - **Big interface (fat interface)**: 매 caller 의 dependency surface 폭증. - **Unit confusion**: 매 Meter / Foot / UserId / OrderId 의 swap silent — 매 brand 필수. - **Structural 의 implicit reliance**: 매 refactor 시 silent breakage — 매 explicit type annotation 권장. ## 🧪 검증 / 중복 - Verified (TypeScript Handbook, Pierce *Types and Programming Languages* 2002, Go Spec). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — TS + Go structural + brand + minimal interface |