타입 정의 규칙
11.1.1. interface vs type 사용 기준
객체의 구조를 정의할 때는 interface를 사용합니다. 유니온, 교차, 조건부 타입은 type을 사용합니다.
typescript
// 객체 형태 — interface 사용
interface User {
id: number
name: string
email: string
role: UserRole
}
// 유니온 타입 — type 사용
type UserRole = 'admin' | 'editor' | 'viewer'
// 교차 타입 — type 사용
type AuditableUser = User & { createdAt: Date; updatedAt: Date }
// 조건부 타입 — type 사용
type ApiResult<T> = T extends void ? { success: boolean } : { success: boolean; data: T }interface는 선언 병합이 가능하므로 확장이 필요한 객체 타입에 적합합니다.type은 타입 연산에 특화되어 있으므로 단순 객체 정의에는 사용하지 않습니다.
11.1.2. 타입 네이밍 규칙
모든 타입과 인터페이스는 PascalCase로 명명합니다. 헝가리안 표기법의 I 접두사는 사용하지 않습니다.
typescript
// 올바른 예
interface UserProfile { id: number; displayName: string }
// 잘못된 예 — I 접두사 금지
interface IUserProfile { id: number; displayName: string }API 관련 타입에는 다음 접미사 패턴을 적용합니다.
| 접미사 | 용도 | 예시 |
|---|---|---|
Request | API 요청 파라미터 | CreateOrderRequest |
Response | API 응답 데이터 | OrderListResponse |
Dto | 계층 간 데이터 전달 객체 | UserDto |
Params | 쿼리 파라미터 | SearchParams |
11.1.3. 타입 파일 관리
타입 정의 파일은 src/types/ 디렉토리에 도메인별로 분리합니다. 각 파일의 타입은 반드시 export합니다.
src/types/
├── user.ts # 사용자 관련 타입
├── product.ts # 상품 관련 타입
├── order.ts # 주문 관련 타입
├── common.ts # 공통 유틸리티 타입
└── index.ts # 배럴 파일 (re-export)typescript
// src/types/user.ts
export interface User {
id: number
name: string
email: string
role: UserRole
}
export type UserRole = 'admin' | 'editor' | 'viewer'
// src/types/index.ts
export type { User, UserRole } from './user'
export type { Product } from './product'- 컴포넌트 전용 타입은 해당 SFC 내에 정의할 수 있습니다. 단, 2개 이상의 파일에서 참조하는 타입은
src/types/로 이동합니다.
11.1.4. any 사용 금지
any는 타입 안전성을 무력화하므로 사용하지 않습니다. 타입을 특정할 수 없는 경우 unknown을 사용합니다.
typescript
// 잘못된 예
function parseData(raw: any): any {
return JSON.parse(raw)
}
// 올바른 예
function parseData(raw: string): unknown {
return JSON.parse(raw)
}ESLint에 @typescript-eslint/no-explicit-any: warn 규칙을 적용합니다. 불가피한 경우 사유 주석을 필수로 작성합니다.
typescript
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- legacy-chart-lib에 타입 정의 없음
const chart = new LegacyChart(canvas) as any- 사유 주석 없이
eslint-disable만 작성하는 것은 허용하지 않습니다. - 코드 리뷰 시
any사용 건은 반드시 검토 대상에 포함합니다.