.d.ts 파일 작성법
타입스크립트는 타입 추론을 통해 많은 타입 정보를 자동으로 얻어낼 수 있지만, 자바스크립트 코드(라이브러리, 프레임워크, 레거시 코드 등)를 타입스크립트 프로젝트에서 사용할 때는 타입 정보를 알 수 없는 경우가 발생합니다. 이럴 때 필요한 것이 바로 타입 선언 파일(Declaration Files), 즉 .d.ts
파일입니다.
.d.ts
파일은 실제 구현 코드 없이, 오직 타입 정보만을 담고 있는 파일입니다. 자바스크립트 코드가 외부에 공개하는 변수, 함수, 클래스 등의 "설명서" 역할을 하며, 타입스크립트 컴파일러는 이 .d.ts
파일을 참조하여 해당 자바스크립트 코드의 타입을 정확하게 이해하고 타입 검사를 수행합니다.
왜 .d.ts
파일이 필요한가?
.d.ts
파일이 필요한 주요 이유는 다음과 같습니다.
자바스크립트 라이브러리 사용: jQuery
, Lodash
, React
등 수많은 자바스크립트 라이브러리들은 .js
파일 형태로 배포됩니다. 타입스크립트 프로젝트에서 이들을 사용할 때, .d.ts
파일이 없으면 해당 라이브러리의 함수나 객체에 접근할 때 any
타입으로 간주되어 타입 검사의 이점을 누릴 수 없습니다.
레거시 자바스크립트 코드 연동: 기존에 작성된 자바스크립트 코드를 타입스크립트 프로젝트에 통합할 때, 명시적인 타입 정보를 제공하여 타입 안전성을 확보합니다.
타입스크립트 라이브러리 배포: 타입스크립트로 작성된 라이브러리를 배포할 때, .ts
파일은 .js
파일과 .d.ts
파일로 컴파일됩니다. 사용자는 .js
파일(실제 구현)과 .d.ts
파일(타입 정보)을 함께 받아 타입스크립트 환경에서 라이브러리를 안전하게 사용할 수 있습니다.
전역 변수/객체 선언: 브라우저 환경에서 window
, document
와 같이 전역 스코프에 존재하는 객체나 변수의 타입을 명시할 때 사용됩니다.
.d.ts
파일의 기본 구조와 declare
키워드
.d.ts
파일은 .ts
파일과 거의 동일한 문법을 사용하지만, declare
키워드를 사용하여 "이것은 실제 구현이 아니라, 단지 타입 정보임을 선언하는 것"을 명시합니다. declare
키워드는 컴파일된 자바스크립트 코드에는 포함되지 않습니다.
주요 declare
사용 예시
declare var
/ declare let
/ declare const
: 전역 변수를 선언합니다.
declare const MY_GLOBAL_CONFIG: {
apiUrl: string;
timeout: number;
};
declare let globalCounter: number;
declare function
: 전역 함수를 선언합니다.
declare function customLog(message: string): void;
declare function calculateSum(...numbers: number[]): number;
declare class
: 클래스를 선언합니다.
declare class MyEventEmitter<T> {
on(eventName: string, listener: (data: T) => void): void;
emit(eventName: string, data: T): void;
}
declare enum
: 열거형을 선언합니다. (자바스크립트 런타임에는 열거형이 없으므로 const enum
처럼 사용될 때 유용)
declare enum StatusCode {
Success = 200,
NotFound = 404,
ServerError = 500
}
declare namespace
: 관련된 전역 변수, 함수, 클래스 등을 하나의 논리적인 그룹으로 묶습니다. (7장 3절 "네임스페이스" 참조)
declare namespace jQuery {
interface Event {
// ...
}
function ajax(url: string, settings?: any): JQueryPromise<any>;
const version: string;
}
declare var $: typeof jQuery; // $도 jQuery 네임스페이스와 동일한 타입을 가짐
이 예시처럼 .d.ts
파일에서 declare namespace
는 전역 스코프에 특정 이름을 가진 객체가 존재하며 그 안에 멤버들이 있음을 선언합니다.
declare module
: 특정 경로 또는 모듈 이름을 가진 자바스크립트 모듈의 타입을 선언합니다.
-
ES 모듈/CommonJS 모듈의 타입 선언
my-custom-module.d.ts declare module 'my-custom-module' { export interface Options { debug: boolean; port: number; } export function init(options: Options): void; export const version: string; export default class Client { // default export constructor(apiUrl: string); getData(): Promise<any>; } }
이 파일을 작성하면, 다른
.ts
파일에서import { init } from 'my-custom-module';
또는import Client from 'my-custom-module';
와 같이 가져올 수 있게 됩니다. -
파일 확장자를 위한 모듈 선언: 웹팩과 같은 번들러를 사용할 때
.css
,.png
등 자바스크립트가 아닌 파일을import
하는 경우가 있습니다. 이들에 대한 타입을 선언할 때도declare module
을 사용합니다.image.d.ts declare module '*.png' { const content: string; // 이미지 파일은 URL 문자열로 로드된다고 가정 export default content; } declare module '*.svg' { import * as React from 'react'; export const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement> & { title?: string }>; const src: string; export default src; }
이제
import myImage from './assets/my-image.png';
와 같이 이미지 파일을 가져와도 타입 오류가 발생하지 않습니다.
.d.ts
파일 작성 팁
필요한 타입만 선언: .d.ts
파일은 실제 구현 코드를 포함하지 않으므로, 자바스크립트 코드가 외부에 노출하는 멤버들만 선언하면 됩니다. 내부적으로만 사용되는 변수나 함수는 선언할 필요가 없습니다.
가능한 한 구체적인 타입 사용: any
타입을 남용하지 않고, 가능한 한 정확하고 구체적인 타입을 사용하여 타입 안전성을 극대화해야 합니다. 제네릭, 유니온 타입, 인터섹션 타입 등을 적극적으로 활용하세요.
불필요한 export
피하기: .d.ts
파일이 모듈이 아닌 전역 타입 선언을 목적으로 한다면, 최상위 레벨에서 export
를 사용하지 않아야 합니다. export
를 사용하면 해당 .d.ts
파일은 모듈로 간주됩니다.
- 전역 선언:
declare var $, declare function jQuery()
- 모듈 선언:
declare module 'lodash' { export function ... }
자동 생성 활용: tsc --declaration
또는 tsc -d
옵션을 사용하면 타입스크립트 소스 코드로부터 .d.ts
파일을 자동으로 생성할 수 있습니다. 이를 기반으로 필요한 부분을 수동으로 수정하는 것이 효율적입니다.
DefinitelyTyped 참조: 가장 널리 사용되는 자바스크립트 라이브러리들은 DefinitelyTyped 프로젝트에서 타입 정의를 제공하며, 이는 @types/
접두사가 붙은 npm 패키지로 배포됩니다 (예: npm install @types/lodash
). 새롭게 .d.ts
파일을 작성하기 전에, 사용할 라이브러리에 대한 타입 정의가 이미 존재하는지 확인하는 것이 좋습니다.
.d.ts
파일의 위치와 컴파일러 설정
.d.ts
파일은 특별히 임포트할 필요 없이 타입스크립트 컴파일러가 자동으로 프로젝트 내에서 찾아 인식합니다.
tsconfig.json
의include
:tsconfig.json
파일의include
배열에.d.ts
파일이 포함된 디렉토리를 지정합니다.- 패키지 내
types
필드: npm 패키지의package.json
파일에types
또는typings
필드를 사용하여 주된 타입 정의 파일의 경로를 명시할 수 있습니다.package.json { "name": "my-cool-lib", "version": "1.0.0", "main": "dist/index.js", "types": "dist/index.d.ts" // 이 필드를 통해 타입스크립트가 타입 정의 파일을 찾음 }
typeRoots
및types
:tsconfig.json
의typeRoots
옵션은 타입 정의 파일을 검색할 루트 디렉토리를 지정하며,types
옵션은 전역적으로 포함할@types
패키지를 명시합니다.
.d.ts
파일은 자바스크립트 생태계와의 상호 운용성을 확보하고 타입스크립트의 타입 안전성이라는 핵심 가치를 유지하는 데 필수적인 요소입니다. 자바스크립트 라이브러리를 사용할 때, 레거시 코드를 통합할 때, 또는 직접 타입스크립트 라이브러리를 개발할 때 .d.ts
파일을 올바르게 작성하고 활용하는 방법을 숙지하는 것이 중요합니다.
다음 절에서는 .d.ts
파일에서 사용되는 declare
키워드의 본질인 앰비언트 선언(Ambient Declarations) 에 대해 더 자세히 알아보겠습니다.