typesinterfaces는 모두 데이터 구조를 정의하기 위한 역할을 하지만, 사용 목적과 설계 철학에서 차이가 있습니다.
NestJS와 같은 대규모 애플리케이션에서는 두 개의 패키지를 구분하여 설계하면 유지보수성과 가독성이 크게 향상됩니다.

1. types 패키지의 역할


2. interfaces 패키지의 역할


구분하여 설계하는 이유

1. 책임 분리(Single Responsibility Principle)

2. 유지보수성 향상

3. 유연성 확보

4. 가독성 향상


적합한 설계 예시

types 패키지

// src/auth/types/oauth-token-response.type.ts
export interface OAuthTokenResponse {
  access_token: string;
  token_type: string;
  refresh_token?: string;
  expires_in: number;
  scope?: string;
  id_token?: string; // OpenID Connect 사용 시
}

// src/auth/types/oauth-user-profile.type.ts
export interface OAuthUserProfile {
  id: string;
  email?: string;
  name?: string | { firstName?: string; lastName?: string };
  picture?: string;
  provider: string;
  raw?: any;
}

interfaces 패키지

// src/auth/interfaces/jwt-payload.interface.ts
export interface JwtPayload {
  sub: string; // 사용자 ID
  email?: string; // 이메일 주소
  provider: string; // OAuth 제공자
  type: 'access' | 'refresh'; // 토큰 유형
}

// src/auth/interfaces/oauth-profile-adapter.interface.ts
export interface OAuthProfileAdapter {
  fromGoogle(rawProfile: any): OAuthUserProfile;
  fromKakao(rawProfile: any): OAuthUserProfile;
  fromApple(rawProfile: any): OAuthUserProfile;
}

typesinterfaces를 구분하는 것은 대규모 애플리케이션에서 필수적인 설계 방식입니다.