--- id: wiki-2026-0508-과잉-속성-체크-epc title: 과잉 속성 체크(EPC) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Excess Property Check, EPC, TypeScript 초과 속성 검사] duplicate_of: none source_trust_level: A confidence_score: 0.92 verification_status: applied tags: [typescript, type-system, structural-typing, frontend] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: TypeScript framework: tsc 5.x --- # 과잉 속성 체크(EPC) ## 매 한 줄 > **"매 object literal 을 매 직접 assign 할 때 매 declared shape 외 매 extra property 을 매 reject"**. TypeScript 의 매 structural typing 은 매 기본적으로 매 width subtype 을 매 허용하지만, 매 object literal 의 매 fresh literal type 은 매 EPC 라는 매 특수 검사 의 매 통과 의 필요. 매 2026 의 TS 5.x 의 매 동일 동작 의 유지, 매 satisfies / 매 as const 의 매 EPC 회피의 X. ## 매 핵심 ### 매 EPC 트리거 조건 - 매 fresh object literal (매 변수 의 매 binding X) - 매 declared type 의 매 존재 (매 parameter, 매 assignment target, 매 return) - 매 declared type 의 매 superset 의 X 인 매 property 의 매 포함 ### 매 EPC 우회 패턴 - 매 변수 의 매 intermediate binding (매 freshness 의 lose) - 매 type assertion (`as T`) — 매 권장 X - 매 index signature (`[k: string]: unknown`) ### 매 응용 1. 매 API option object 의 매 typo 방지. 2. 매 React props 의 매 unknown prop 차단. 3. 매 config schema 의 매 strict validation. ## 💻 패턴 ### EPC 발동 (기본) ```typescript interface ButtonProps { label: string; onClick: () => void; } function render(props: ButtonProps) {} // ❌ Error: Object literal may only specify known properties, and 'icon' does not exist in type 'ButtonProps' render({ label: "Save", onClick: () => {}, icon: "💾" }); ``` ### Intermediate binding 우회 (의도적이지 않은 경우 위험) ```typescript const extra = { label: "Save", onClick: () => {}, icon: "💾" }; render(extra); // ✅ 통과 — fresh 아니어서 EPC 미발동, structural width subtyping 만 검사 ``` ### satisfies 와 EPC ```typescript // satisfies 도 EPC 적용 — extra property reject const config = { label: "Save", onClick: () => {}, // icon: "💾", // ❌ EPC error } satisfies ButtonProps; ``` ### Index signature 로 의도적 허용 ```typescript interface FlexibleProps { label: string; [key: string]: unknown; } function render2(p: FlexibleProps) {} render2({ label: "Save", extra: 123 }); // ✅ ``` ### Discriminated union 과 EPC ```typescript type Action = | { type: "add"; value: number } | { type: "remove"; id: string }; function dispatch(a: Action) {} // ❌ EPC: 'value' 와 'id' 동시 존재 reject dispatch({ type: "add", value: 1, id: "x" }); ``` ### React props 에 적용 ```tsx type Props = { name: string }; function Hello(props: Props) { return

{props.name}

; } // ❌ EPC: 'age' is not in Props ; ``` ### 회피 안티패턴 (지양) ```typescript // ❌ as 캐스팅 — 런타임 typo 방치 render({ label: "Save", onClick: () => {}, icon: "💾" } as ButtonProps); ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | API option literal | EPC 활용 — typo 차단 | | 동적 prop forward | spread + 명시 typing | | 외부 라이브러리 객체 | `satisfies` 우선, `as` 회피 | | 의도된 extra metadata | index signature 도입 | **기본값**: EPC 의 매 의존, 매 `as` 캐스팅 의 X, 매 `satisfies` 의 매 우선. ## 🔗 Graph - 부모: [[TypeScript Type System]] · [[Structural Typing]] - 변형: [[Width Subtyping]] · [[Fresh Literal Types]] - 응용: [[satisfies Operator]] · [[React Props Typing]] - Adjacent: [[Discriminated Unions]] · [[Index Signatures]] ## 🤖 LLM 활용 **언제**: 매 object literal 직접 전달 시 매 typo / 매 stale prop 의 매 정적 차단 의 필요. **언제 X**: 매 plugin / 매 forward props / 매 metadata pass-through — 매 index signature 또는 매 generic constraint 의 매 권장. ## ❌ 안티패턴 - **as 캐스팅 의존**: EPC 무력화, 런타임 버그 양산. - **`@ts-ignore` 로 무시**: 검사 의도 자체 의 폐기. - **모든 type 에 `[k: string]: unknown`**: EPC 의 효과 의 상실. ## 🧪 검증 / 중복 - Verified (TypeScript Handbook — Object Literals & Excess Property Checks, TS 5.4+). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — EPC trigger / 우회 패턴 / satisfies 의 동작 정리 |