본문 바로가기
Javascript/Next.js

Next.js에서 .d.ts 파일 왜 쓰는가???

by daddydontsleep 2024. 12. 19.
728x90
728x90

사진: UnsplashKarsten Winegeart

Next.js 프로젝트에서 TypeScript를 사용할 때, 타입을 선언하는 방법에는 여러 가지가 있습니다. 그 중에서도 .d.ts 파일을 사용하는 방식이 있는데, 이는 단순한 타입 선언 이상의 의미를 가지고 있습니다. 이번 글에서는 .d.ts 파일의 특징과 일반 TypeScript 파일과의 차이점, 그리고 언제 어떻게 사용해야 하는지 자세히 알아보겠습니다.

.d.ts 파일이란?

.d.ts 파일은 TypeScript Declaration File의 약자로, 타입 선언만을 포함하는 특별한 파일입니다. 이 파일에는 실제 구현 코드가 들어가지 않으며, 오직 타입 정의만 포함됩니다.

// types.d.ts
declare interface User {
  id: number;
  name: string;
  email: string;
}

declare type AuthResponse = {
  token: string;
  user: User;
}

.ts 파일과 .d.ts 파일의 주요 차이점

1. 구현 코드 포함 여부

  • .ts 파일
    • 실제 구현 코드와 타입 선언을 모두 포함할 수 있습니다.
    • 런타임에 실행되는 JavaScript 코드로 컴파일됩니다.
// user.ts
interface User {
  id: number;
  name: string;
}

export class UserService {
  getUser(id: number): User {
    // 실제 구현 코드
    return { id, name: 'John Doe' };
  }
}
  • .d.ts 파일
    • 오직 타입 선언만 포함합니다.
    • JavaScript로 컴파일cript로 컴파일
    • 개발 시점의 타입 체크와 자동완성에만 사용됩니다.

2. 용도와 사용 시점

.d.ts 파일을 사용하는 경우

  1. 전역 타입 선언
// global.d.ts
declare namespace NodeJS {
  interface ProcessEnv {
    NEXT_PUBLIC_API_URL: string;
    DATABASE_URL: string;
  }
}
  1. 외부 라이브러리 타입 정의
// custom-library.d.ts
declare module 'custom-library' {
  export function doSomething(): void;
  export interface Options {
    timeout: number;
  }
}
  1. 공통 타입 정의
// api.d.ts
declare interface ApiResponse<T> {
  data: T;
  status: number;
  message: string;
}

.ts 파일을 사용하는 경우

  1. 컴포넌트나 함수 구현
  2. 실제 비즈니스 로직 구현
  3. 타입과 구현이 함께 필요한 경우

.d.ts 파일을 사용하는 이유

  1. 타입 정의의 중앙화
    • 프로젝트 전체에서 사용되는 타입들을 한 곳에서 관리할 수 있습니다.
    • 타입 정의의 일관성을 유지하기 쉽습니다.
  2. 번들 크기 최적화
    • .d.ts 파일은 런타임 코드를 생성하지 않으므로 번들 크기에 영향을 주지 않습니다.
    • 타입 정보만 필요한 경우 불필요한 코드 생성을 방지합니다.
  3. 타입 선언의 명확한 분리
    • 타입 정의와 구현 코드를 명확하게 분리할 수 있습니다.
    • 코드의 가독성과 유지보수성이 향상됩니다.

실제 사용 예시

1. 환경 변수 타입 정의

// env.d.ts
declare namespace NodeJS {
  interface ProcessEnv {
    NEXT_PUBLIC_API_URL: string;
    NEXT_PUBLIC_GA_ID: string;
    DATABASE_URL: string;
    JWT_SECRET: string;
  }
}

2. API 응답 타입 정의

// api.d.ts
declare namespace API {
  interface Response<T = any> {
    data: T;
    status: number;
    message: string;
  }

  interface PaginatedResponse<T> extends Response<T> {
    total: number;
    page: number;
    limit: number;
  }
}

3. 전역 유틸리티 타입 정의

// utils.d.ts
declare type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};

declare type Nullable<T> = T | null;

모범 사례와 주의사항

모범 사례

  1. 명확한 네이밍 컨벤션 사용
    • 목적이 명확한 파일명 사용 (예: api.d.ts, models.d.ts)
    • 관련된 타입들을 동일한 파일에 그룹화
  2. 네임스페이스 활용
    • 관련된 타입들을 네임스페이스로 그룹화
    • 이름 충돌 방지
  3. 문서화
    • JSDoc을 사용한 타입 설명 추가
    • 복잡한 타입의 경우 사용 예시 포함

주의사항

  1. 중복 선언 피하기
    • 동일한 타입을 여러 파일에서 선언하지 않기
    • 필요한 경우 import/export 사용
  2. 과도한 사용 피하기
    • 구현이 필요한 경우는 .ts 파일 사용
    • 불필요한 타입 선언 파일 생성 지양

결론

.d.ts 파일은 Next.js 프로젝트에서 타입 시스템을 효과적으로 관리하기 위한 강력한 도구입니다.
타입 정의의 중앙화, 번들 크기 최적화, 그리고 코드와 타입의 명확한 분리를 통해 더 maintainable한 코드베이스를 만들 수 있습니다.
하지만 모든 상황에서 .d.ts 파일이 최선의 선택은 아니며, 프로젝트의 요구사항과 상황에 따라 적절한 사용이 필요합니다.
이 글이 Next.js 프로젝트에서 타입 선언 파일을 효과적으로 사용하는 데 도움이 되길 바랍니다.
여러분의 프로젝트에서 타입 시스템을 어떻게 관리하고 계신가요? 댓글로 여러분의 경험을 공유해 주세요!

태그: #NextJS #TypeScript #웹개발 #프론트엔드 #타입스크립트 #타입선언 #개발팁 #dts #React #자바스크립트 #코딩 #프로그래밍 #개발자 #타입시스템

728x90
300x250