본문으로 건너뛰기

선언 파일과 @types

타입스크립트 목차모듈·선언·설정레슨 45 / 51

목차

선언 파일(.d.ts)은 실제 동작하는 함수 본문이나 값 없이 오직 타입 모양만 적어 둔 파일입니다. Node가 실행 때 제공하는 process·fs나 자바스크립트로만 작성된 외부 패키지는 .ts 원본이 없으므로, @types/node 같은 선언 패키지의 .d.ts 파일을 통해 검사기에 타입을 알려 줍니다.

Node가 프로그램에 기본으로 넣어 주는 process.version(현재 Node 버전 문자열)을 예제로 삼아, 왜 선언이 없으면 TS2591 오류가 나는지, 그리고 @types/node와 tsconfig.json의 "types" 설정이 어떻게 연결되는지 살펴봅니다.

4단계 중 1단계. 1~4번 줄의 `legacy-pos.js`는 타입이 없는 순수 자바스크립트 파일입니다. 설명서 파일(`.d.ts`) 없이 9번 줄에서 바로 가져오면 검사기는 타입을 알 수 없어 `TS7016` 오류를 냅니다.

1실행 때는 있는데 검사기는 모르는 이름 (TS2591)

Node로 프로그램을 실행하면 process라는 전역 객체가 자동으로 준비되어 있어서, process.version으로 현재 Node 판을 읽을 수 있습니다. 그런데 과목 기본 설정("types": [])에서 아래 한 줄을 검사하면 TS2591 오류가 납니다.

console.log(process.version);
검사 결과 오류 1개
main.ts(1,13): error TS2591: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.

Node는 process를 알고 있어서 바로 실행하면 버전을 잘 찍지만, 타입 검사기(tsc)는 이 코드가 브라우저에서 돌지 Node에서 돌지 스스로 짐작하지 않습니다. 그래서 process라는 이름의 타입 선언이 어디에도 없다며 막는 것입니다.

2@types/node와 "types": ["node"] 연결하기

검사기에 Node 전용 이름들을 알려 주려면 두 걸음이 필요합니다.

  1. 선언 패키지 설치: 터미널에서 npm i -D @types/node를 실행해 Node 내장 기능들의 .d.ts 묶음을 node_modules/@types/node⁠에 받습니다.
  2. tsconfig.json에 등록: tsconfig.json의 "types" 배열에 "node"를 적어 검사기가 그 선언 파일을 읽게 합니다.
{
  "compilerOptions": {
    "types": ["node"]
  }
}

TypeScript 7.0부터는 "types"의 기본값이 빈 배열([])입니다. 따라서 @types/node를 설치하기만 해서는 자동으로 읽히지 않고, "types": ["node"]처럼 쓸 선언 이름을 직접 적어 주어야 합니다.

3.d.ts 파일 안에는 무엇이 들어 있을까?

.d.ts 파일 안에는 interface, type과 함께 declare 키워드가 적혀 있습니다. declare는 "실제 값은 실행 환경(Node나 브라우저, 외부 JS 파일)이 이미 만들어 두었으니 검사기는 이 타입 표만 믿고 통과시켜라"라는 뜻입니다.

// 예: index.d.ts 안의 선언 모양
declare const VERSION: string;
declare function beep(
  times: number,
): void;

이 줄들은 값이나 함수 본문({ ... })이 전혀 없으며, 타입 지우기 단계에서 통째로 사라집니다.

파일 종류들어 있는 것타입 지우기 뒤
.ts 파일타입 표기 + 실제 실행 코드타입만 지워지고 실행 코드가 남음
.d.ts 선언 파일interface · type · declare 선언만실행 코드가 없어 아무것도 남지 않음

예제

실행 결과를 먼저 적어 본 뒤 펼쳐 보세요. 맞혀 보기는 점수에 들지 않습니다.

설정을 나타내는 interface CafeEnv와 실제 객체 env를 함께 적은 코드입니다.

interface CafeEnv {
  store: string;
  openHour: number;
}
// declare const ENV: CafeEnv;
const env: CafeEnv = {
  store: "강남점",
  openHour: 8,
};
console.log(
  env.store,
  env.openHour,
);

무엇이 찍힐까요?

실행 결과 보기
실행 결과
강남점 8

.d.ts 파일에는 interface CafeEnv와 declare const ENV: CafeEnv;⁠처럼 타입과 모양만 적고, 실제 객체 값은 실행 환경이나 .ts·.js 코드가 제공합니다.

자주 틀리는 곳

틀린 생각: .d.ts나 declare를 적으면 실행 코드도 함께 만들어진다.

declare const coupon: number;⁠라고 적으면 검사기는 coupon이라는 숫자가 실제로 존재한다고 믿고 검사를 통과시킵니다(검사 규칙 6 — 선언 파일을 믿는다). 하지만 .d.ts와 declare는 실행 코드를 전혀 만들지 않으므로, 실행 환경에 실제 coupon 값이 없으면 Node 실행 때 ReferenceError로 멈춥니다.

declare const coupon: number;
console.log(coupon + 500);
실행 결과
main.ts:2console.log(coupon + 500);            ^ ReferenceError: coupon is not defined    at main.ts:2:13

맞는 규칙: declare와 .d.ts는 오직 검사기에게 타입만 알려 줄 뿐 실행 때 아무 값도 만들지 않습니다(타입이 실행 때 남는다는 생각).

틀린 생각: @types/node 패키지를 설치만 하면 저절로 적용된다.

예전 버전(TypeScript 5 이하) 글을 보고 npm i -D @types/node만 치면 바로 동작한다고 생각하기 쉽습니다.

맞는 규칙: TypeScript 6.0·7.0과 과목 tsconfig.json에서는 "types": []가 기본이므로, 설치한 뒤 반드시 tsconfig.json의 "types" 배열에 "node"를 추가해야 검사기가 읽습니다.

틀린 생각: 선언 파일에 실제 값과 다른 타입을 적어도 검사기가 알아차린다.

검사기는 .d.ts나 declare에 적힌 타입을 의심하지 않고 그대로 믿습니다(검사 규칙 6).

맞는 규칙: 선언 파일이 거짓말을 하면 검사는 통과하고 실행 때 오류가 납니다. 또한 타입 선언이 없는 옛 npm 패키지를 가져오면 TS7016 오류가 나며, @types/패키지이름을 설치하거나 declare module로 모양을 알려 주어야 합니다.

확인 문제

1. 과목 기본 tsconfig.json("types": [])에서 console.log(process.version)⁠을 검사하면 왜 TS2591 오류가 날까요?

힌트

2절에서 "types": []가 어떤 의미인지 살펴보세요.

정답

"types": [] 상태에서는 검사기가 Node 전용 선언 파일을 읽지 않기 때문입니다. @types/node를 설치하고 tsconfig.json에 "types": ["node"]를 추가하면 process.version의 타입(string)을 알아봅니다.

2. declare const bonus: number; 한 줄만 적고 console.log(bonus)를 실행하면 검사와 실행 결과는 각각 어떻게 되나요?

힌트

declare가 검사기에게 하는 일과 실행 때 남는 코드를 나누어 생각해 보세요.

정답

타입 검사는 오류 0으로 통과하지만, 실행 때는 bonus가 없다며 ReferenceError로 멈춥니다. declare는 검사기에게 "값이 있다"고 믿게만 할 뿐(검사 규칙 6), 실제 실행 값을 만들지 않기 때문입니다(타입이 실행 때 남는다는 생각).

3. .ts 파일과 .d.ts 선언 파일의 가장 큰 차이는 무엇인가요?

힌트

3절의 비교 표를 떠올려 보세요.

정답

.ts 파일에는 타입과 실제 실행 코드가 함께 들어 있지만, .d.ts 파일에는 실행 코드 없이 타입 선언만 들어 있습니다.

컴퓨터에서 해 보기(선택) — 점수에 들지 않습니다. 폰으로만 보고 있다면 건너뛰세요. 작업 폴더에서 npm i -D @types/node를 실행하고 tsconfig.json의 "types"를 ["node"]로 바꾼 뒤 console.log(process.version);⁠이 npx tsc를 오류 0으로 통과하는지 확인해 보세요. 다음 레슨 DOM 요소의 타입에서는 브라우저 선언 파일이 주는 DOM 요소 타입을 다룹니다. 검사하고 돌리는 법은 내 컴퓨터에서 검사하고 돌리기에 있습니다.

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

타입스크립트 목차로