kind: capsule status: active visibility: private license: CC-BY-SA-4.0 summary: interface는 객체/클래스 shape와 declaration merging에 강하고, type은 union/intersection/primitive/mapped/conditional/template literal 등 type expression 전반에 강하다. 실무 권장: 확장 가능한 public object API는 interface, 조합·계산 타입은 type. tags: - typescript - type-system - interface - type-alias - capsule
TypeScript interface vs type Capsule
Summary#
interface와 type은 TypeScript에서 객체 shape 표현에는 대부분 호환된다. 핵심 차이는 interface가 객체 shape 선언, extends, declaration merging에 특화되어 있고, type은 union/intersection/primitive/tuple/mapped/conditional/template literal types 등 임의의 type expression에 이름을 붙이는 범용 도구라는 점이다.
실무 기본값은 다음처럼 잡으면 안전하다.
- 외부에 확장될 수 있는 public object API: interface 선호
- union, primitive alias, tuple, mapped/conditional/template literal type, 복잡한 조합 타입: type 사용
- 팀 스타일이 이미 정해져 있으면 일관성을 우선한다.
Claim#
interface가 특히 강한 것#
- Declaration merging: 같은 이름의 interface를 여러 번 선언하면 자동 병합된다. 라이브러리 augmentation, 전역 타입 확장 등에 유용하다.
typescript interface Window { myCustom?: string; } // lib.dom의 Window shape 확장 - 객체/클래스 shape 선언:
extends체인과 public API 문서화에 자연스럽다.typescript interface User { id: string; name: string } interface Admin extends User { role: "admin" } class Person implements User { constructor(public id: string, public name: string) {} }
type이 특히 강한 것#
- Union / Intersection / Primitive alias
typescript type ID = string | number; type Direction = "up" | "down" | "left" | "right"; type AdminUser = User & { role: "admin" }; - Tuple alias
typescript type Pair = [string, number]; - Mapped / Conditional / Template literal types
typescript type ReadonlyFields<T> = { readonly [K in keyof T]: T[K] }; type NonNull<T> = T extends null | undefined ? never : T; type CSSVar = `--${string}`;
공통점#
- 객체 shape는 둘 다 표현 가능하다.
typescript interface UserA { id: string } type UserB = { id: string }; - 확장은 둘 다 가능하다.
interface는extends,type은 intersection을 주로 쓴다.typescript interface B extends A { extra: string } type B2 = A & { extra: string }; class implements는 interface가 가장 일반적이지만, 객체 타입을 나타내는 type alias도 구현 대상이 될 수 있다. 단, union처럼 정적으로 확정된 객체 멤버 집합이 아닌 타입은implements대상으로 부적절하다.typescript type Named = { name: string }; class Dog implements Named { constructor(public name: string) {} }- 일반적인 객체 shape 수준에서는 성능 차이를 과장하지 않는 것이 좋다. 오류 메시지, 표시 방식, 복잡한 타입 계산에서는 체감 차이가 날 수 있지만 선택의 1차 기준은 표현력과 확장성이다.
Scope#
- TypeScript 현대 버전 전반의 실무 기준.
- Template literal types 등 일부 고급 기능은 TypeScript 4.1+ 기능이다.
- 라이브러리 작성자: 외부 augmentation/확장 가능성을 열어둘 public object API는
interface를 우선 검토한다. - 애플리케이션 내부: union, discriminated union, utility type 조합, mapped/conditional type은
type을 사용한다.
Caveats#
- interface declaration merging은 의도치 않은 전역 오염 위험이 있다. global scope나
declare global사용 시 신중해야 한다. - 동일 이름 재선언에서
interface는 병합되고,typealias는 중복 선언 에러가 난다. 이 차이는 의도 명확성 측면에서 중요하다. typealias는 union, conditional, mapped type처럼 interface로 표현할 수 없는 계산 타입을 담을 수 있다.- 반대로 declaration merging이 필요한 확장 포인트는
interface가 더 적합하다. - ‘항상 interface’ 또는 ‘항상 type’ 같은 절대 규칙보다, public 확장성·표현력·팀 컨벤션을 함께 고려한다.
Source#
- Q: https://stackoverflow.com/q/37233735
- A: https://stackoverflow.com/a/37233777 — by Binary Birch Tree
- License: CC BY-SA 4.0 (Stack Exchange)
- TypeScript Handbook: https://www.typescriptlang.org/docs/handbook/
- 조회일: 2026-04-19
Sagwan Revalidation 2026-04-19T01:49:59Z#
- verdict:
ok - note: TypeScript 5.x 기준으로도 interface/type 핵심 차이와 권장 패턴은 여전히 유효하며 오탈자·모순 없음.
Sagwan Revalidation 2026-04-20T02:27:49Z#
- verdict:
ok - note: TypeScript 5.x 기준으로도 interface/type 의 핵심 구분과 권장안은 변함없으며 내용 정확함.
Sagwan Revalidation 2026-04-21T02:43:49Z#
- verdict:
ok - note: LLM unavailable: [CLI 오류 1] SessionEnd hook [node "/home/insu/.pixel-agents/hooks/claude-hook.js"] failed: node:internal/modules/cjs/load
Sagwan Revalidation 2026-04-22T03:14:36Z#
- verdict:
ok - note: LLM unavailable: [CLI 오류 1] SessionEnd hook [node "/home/insu/.pixel-agents/hooks/claude-hook.js"] failed: node:internal/modules/cjs/load
Sagwan Maintenance 2026-05-07#
- verdict:
revise - note: 핵심 주장은 유지하되,
class implements를 interface 전용처럼 보이게 한 표현을 수정했다. 객체 타입을 나타내는 type alias도 class implements 대상이 될 수 있으므로 ‘interface가 가장 일반적’으로 완화했다. Scope의type은 2.0에 도입문구는 오류 소지가 있어 제거하고, template literal types의 4.1+ 범위만 남겼다.