본문으로 건너뛰기
김신건의 로그

[TypeScript] Declaration Files (.d.ts)

· 수정 · 📖 약 2분 · 691자/단어 #typescript #declaration #ambient #types
TypeScript Declaration Files, TS d.ts, TypeScript type definitions, ambient declaration, declare module, declare global, DefinitelyTyped, @types packages, TS 선언 파일

정의

Declaration File (.d.ts) 은 타입 정보만 담은 파일입니다. 실행 코드 없이 함수, 클래스, 변수, 모듈의 타입 시그니처 만 선언합니다. JavaScript 라이브러리를 TypeScript 에서 안전하게 사용하기 위한 다리 역할을 합니다.

  • 자동 생성: tsc --declaration.ts 소스에서 .d.ts 자동 생성 (라이브러리 배포용)
  • 수동 작성: 순수 JS 라이브러리에 타입 부여

기본 문법

// mylib.d.ts
declare function greet(name: string): string;
declare const VERSION: string;
declare class Client {
  constructor(url: string);
  send(msg: string): Promise<void>;
}

declare 는 “이것은 런타임에 존재한다고 가정하고 타입만 부여” 를 의미. Emit 안 됨.

Ambient Module

외부 (npm) 모듈 타입 선언:

// mylib.d.ts
declare module "cool-lib" {
  export function coolFn(x: number): string;
  export const version: string;
  export default class Cool {
    constructor(opts: {debug?: boolean});
    activate(): Promise<void>;
  }
}

이후:

import Cool, {coolFn, version} from "cool-lib";

와일드카드 모듈

// assets.d.ts
declare module "*.png" {
  const url: string;
  export default url;
}

declare module "*.svg" {
  import type {ComponentProps, FC} from "react";
  const svg: FC<ComponentProps<"svg">>;
  export default svg;
}

// 사용
import logo from "./logo.png";       // logo: string
import Icon from "./icon.svg";        // Icon: React component

Ambient Variable

declare const process: {
  env: Record<string, string | undefined>;
};

declare const window: Window & {
  myGlobal?: string;
};

이런 것들은 lib.dom.d.ts, @types/node 등이 이미 제공.

Global Augmentation

기존 전역 타입 확장:

// global.d.ts
export {};  // 이 파일을 모듈로 표시 (declare global 사용에 필요)

declare global {
  interface Window {
    myApp: {
      version: string;
      init(): void;
    };
  }

  interface String {
    reverse(): string;   // String prototype 확장
  }

  namespace NodeJS {
    interface ProcessEnv {
      NEXT_PUBLIC_API_URL: string;
      DATABASE_URL: string;
    }
  }
}

process.env.DATABASE_URL 이 타입 안전. Undefined 없음.

Module Augmentation

기존 npm 모듈 확장:

// express-augment.d.ts
import "express";   // 원본 모듈 로드

declare module "express" {
  interface Request {
    userId?: string;
    auth?: {token: string};
  }
}

이제 req.userId, req.auth 를 어디서든 접근 가능. 인증 미들웨어 패턴에 필수.

JSX augmentation (React)

// custom-elements.d.ts
declare namespace JSX {
  interface IntrinsicElements {
    "my-widget": {color?: string; size?: "sm" | "md" | "lg"};
  }
}

// 사용
<my-widget color="red" size="md" />

Web Component 사용 시 유용.

Declaration Merging

같은 이름의 interface / namespace 를 여러 파일에서 선언하면 자동 병합:

// file1.d.ts
interface Config {port: number}

// file2.d.ts
interface Config {host: string}

// = interface Config {port: number; host: string}

Interface merge 만 됨. Type alias 는 안 됨.

Types-only import in .d.ts

Declaration 파일 안에서 타입 가져오기:

// mylib.d.ts
import type {Request, Response} from "express";

declare module "mylib" {
  export function middleware(req: Request, res: Response): void;
}

Triple slash directive (legacy)

/// <reference path="./other.d.ts" />
/// <reference types="node" />

지양. import type 이나 tsconfig types 배열로 대체.

DefinitelyTyped

Community 유지 npm 패키지 타입 저장소. @types/* 스코프로 배포.

npm install --save-dev @types/node @types/express @types/react

라이브러리가 자체 타입을 포함하면 @types 불필요. package.jsontypes / typings 필드로 지정.

라이브러리 자체 타입 포함

{
  "name": "mylib",
  "main": "dist/index.js",
  "types": "dist/index.d.ts"
}

tsc --declaration 로 emit 한 .d.tstypes 로 노출.

Types 조회 순서

Import 시 TypeScript 는:

  1. 자체 .d.ts (package.json 의 types)
  2. @types/{name} 패키지
  3. 찾을 수 없음 -> noImplicitAny 상태에 따라 오류 또는 any

declaration: true (라이브러리 빌드)

{
  "compilerOptions": {
    "declaration": true,           // .d.ts 생성
    "declarationMap": true,         // .d.ts.map (IDE go-to-definition)
    "emitDeclarationOnly": false,   // .js 도 emit
    "outDir": "./dist"
  }
}

rollup + dts plugin (bundle .d.ts)

큰 라이브러리는 .d.ts 를 하나로 번들:

npm i -D rollup-plugin-dts
// rollup.config.js
import dts from "rollup-plugin-dts";

export default {
  input: "./dist/index.d.ts",
  output: [{file: "./dist/bundled.d.ts", format: "es"}],
  plugins: [dts()],
};

실전: env vars 타입

// env.d.ts
declare namespace NodeJS {
  interface ProcessEnv {
    NODE_ENV: "development" | "production" | "test";
    DATABASE_URL: string;
    SECRET_KEY: string;
    PORT?: string;
  }
}

process.env.DATABASE_URLstring 으로 (undefined 없이). 물론 실제 undefined 방어는 별도.

실전: CSS Modules

// css-modules.d.ts
declare module "*.module.css" {
  const classes: {readonly [key: string]: string};
  export default classes;
}

declare module "*.module.scss" {
  const classes: {readonly [key: string]: string};
  export default classes;
}

// 사용
import styles from "./Button.module.css";
<button className={styles.primary}>Click</button>

실전: Vite 환경

// vite-env.d.ts
/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_API_URL: string;
  readonly VITE_APP_NAME: string;
}

interface ImportMeta {
  readonly env: ImportMetaEnv;
}

함정

WARNING

declare global 은 module 안에만. 파일이 module (import / export 포함) 이어야 함. 상단에 export {}; 트릭.

CAUTION

Ambient 는 컴파일 시만. 실제 런타임에 그 module 이 없으면 오류. 파일 매핑 (webpack, vite alias) 필요.

WARNING

@types 버전 불일치. 라이브러리 버전과 다른 @types 버전이면 타입 오류. npm-check-updates 로 동기화.

IMPORTANT

자체 타입 포함 시 @types 무시하도록. package.jsontypes 필드가 최우선.

CAUTION

JSDoc 도 있음. .d.ts 대신 JSDoc 으로 타입 부여 가능 (@type, @param). 순수 JS 라이브러리 문서화에 활용.

관련 위키

이 글의 용어 (6개)
[Javascript] ES Modules (import / export)javascript
정의 ES Modules (ESM) 은 표준 JS 모듈 시스템 (ES6). / 키워드. 브라우저와 Node.js 16+ 모두 지원. export named export defau…
[TypeScript] Genericstypescript
정의 Generics 는 타입을 파라미터화하는 문법입니다. 함수, 클래스, 인터페이스, type alias 가 재사용 가능 하면서도 타입 안전 하도록 만듭니다. Java 의 ge…
[TypeScript] Interfacestypescript
정의 Interface 는 객체의 shape (형태) 을 정의하는 TypeScript 문법입니다. 필드, 메서드, 인덱스 시그니처, 호출 시그니처를 선언하며, 로 상속하고 dec…
[TypeScript] Modules (import/export, moduleResolution)typescript
정의 TypeScript 모듈 시스템은 ES Modules (ESM) 를 기본 언어 모델로 삼되, CommonJS (CJS) 를 상호운용성 (interop) 계층으로 지원합니다.…
[TypeScript] Strict Mode & tsconfigtypescript
정의 Strict Mode 는 여러 엄격한 타입 검사 플래그를 한 번에 켜는 옵션 ( ) 입니다. 강력한 타입 안전성을 제공하지만, 기존 코드베이스에는 대량의 오류를 발생시킬 수…
TypeScripttypescript
정의 TypeScript 는 Microsoft 가 2012년 발표한 JavaScript 의 상위 집합 프로그래밍 언어입니다. 정적 타입 시스템, 인터페이스, 제네릭, enum, …

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기