Skip to content

타입 정의 규칙

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 관련 타입에는 다음 접미사 패턴을 적용합니다.

접미사용도예시
RequestAPI 요청 파라미터CreateOrderRequest
ResponseAPI 응답 데이터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 사용 건은 반드시 검토 대상에 포함합니다.

TIENIPIA QUALIFIED STANDARD