본문으로 건너뛰기

모듈과 타입 내보내기

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

목차

프로그램이 커지면 타입 선언과 함수를 여러 파일로 나누어 담습니다. 타입스크립트에서는 값(const, function)뿐 아니라 interface나 type 별칭 앞에도 export를 붙여 내보낼 수 있고, 다른 파일에서 타입을 가져올 때는 import type을 써서 실행 전에 통째로 지워질 줄임을 분명히 표시합니다.

메뉴 모양(Menu)과 가격(latte)을 menu.ts에서 내보내고 main.ts에서 가져오는 흐름을 따라가며, 왜 타입에는 import type을 쓰고 경로 끝에 .ts 확장자를 붙이는지 살펴봅니다.

JS 다시 보기: 파일 나누기: import와 export에서 파일마다 값을 내보내고 가져오는 기본 문법을 다뤘습니다.

이 단원을 이미 안다면 단원 연습 문제의 진단 문항부터 풀고 틀린 레슨만 보세요.

4단계 중 1단계. `menu.ts`에서 내보낸 `Drink`는 타입에만 쓰이므로 11번 줄처럼 `import type { Drink }`로 가져오고, 실제 실행할 함수 `formatDrink`는 12번 줄처럼 일반 `import`로 가져옵니다.

1타입과 값을 내보내고 가져오는 법

값과 마찬가지로 interface나 type 선언 앞에도 export를 붙이면 다른 파일에서 가져다 쓸 수 있습니다. 먼저 menu.ts 파일에 Menu 인터페이스와 latte 가격 상수를 내보냅니다.

// menu.ts
export interface Menu {
  item: string;
  price: number;
}

export const latte = 4500;

이제 main.ts에서 Menu 타입과 latte 값을 가져옵니다. 이때 타입은 import type으로, 실행 때 쓰이는 값은 일반 import로 구분해 적습니다.

// main.ts
import type {
  Menu,
} from "./menu.ts";
import {
  latte,
} from "./menu.ts";

const m: Menu = {
  item: "라테",
  price: latte,
};
console.log(m.item, m.price);

한 줄에 함께 가져오고 싶다면 타입 이름 앞에만 type 키워드를 붙이는 인라인 표기({ type Menu, latte })를 써도 됩니다.

// main.ts (한 줄로 합친 꼴)
import {
  type Menu,
  latte,
} from "./menu.ts";

2왜 import type을 따로 구분할까?

Node가 .ts 파일을 바로 실행할 때는 각 파일의 타입 표기를 지우기만 합니다.

  1. menu.ts의 export interface Menu { ... }⁠는 타입 지우기 단계에서 흔적 없이 사라집니다. 실행 시점의 menu.ts에는 export const latte = 4500; 한 줄만 남습니다.
  2. main.ts의 import type { Menu } 줄도 통째로 지워지므로, Node는 latte 값만 안전하게 가져와 라테 4500을 찍습니다.

만약 type을 빼먹고 import { Menu }처럼 일반 값 import로 적으면 어떻게 될까요?

  • 타입 검사(npx tsc): 과목 설정의 verbatimModuleSyntax가 타입은 반드시 타입 전용 가져오기로 적으라며 TS1484 오류로 즉시 막아 줍니다.
  • Node 실행(node main.ts): import { Menu } 줄이 지워지지 않고 남아서, 이미 Menu가 지워진 menu.ts에서 실행 값을 찾다가 SyntaxError로 멈춥니다.
가져오는 대상쓰는 문법타입 지우기 뒤
interface · type 별칭import type \{ Menu \}줄 통째로 사라짐
const · function · class(값)import \{ latte \}그대로 남아 실행됨
한 줄에 섞어 가져올 때import \{ type Menu, latte \}type Menu만 사라지고 latte만 남음

예제

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

Order 인터페이스와 calc 함수를 정의하고 주문 금액을 계산합니다.

interface Order {
  item: string;
  qty: number;
}

function calc(o: Order) {
  return o.qty * 4000;
}

const myOrder: Order = {
  item: "커피",
  qty: 2,
};
console.log(calc(myOrder));

무엇이 찍힐까요? 또한 Order와 calc를 다른 파일에서 한 줄로 함께 가져온다면 어떻게 적을까요?

실행 결과 보기
실행 결과
8000

Order는 타입 지우기 때 사라지는 인터페이스이므로 다른 파일에서 가져올 때 앞에 type을 붙여 { type Order, calc }처럼 적고, 실행 때 호출할 함수 calc는 일반 이름으로 가져옵니다.

자주 틀리는 곳

틀린 생각: 타입을 import하면 실행 때에도 어떤 객체가 넘어온다.

import type { Menu }로 가져온 Menu는 오직 : Menu 같은 타입 자리에만 쓸 수 있습니다(타입이 실행 때 남는다는 생각). 값 자리에 console.log(Menu)처럼 쓰면 타입을 값으로 썼다며 TS2693 오류가 납니다.

interface Menu {
  item: string;
  price: number;
}

console.log(Menu);
검사 결과 오류 1개
main.ts(6,13): error TS2693: 'Menu' only refers to a type, but is being used as a value here.

맞는 규칙: interface와 type 별칭은 실행 전에 지워지므로 값 자리에 놓을 수 없고, 가져올 때도 import type으로 구분해 적습니다.

틀린 생각: Node로 .ts 파일을 직접 돌릴 때도 파일 경로 끝에 확장자를 생략하거나 .js로 적는다.

확장자를 빼먹고 "./menu"만 적으면 검사기는 TS2835 오류를 내고, Node도 파일을 찾지 못해 멈춥니다.

맞는 규칙: Node가 .ts 파일을 직접 실행하는 환경에서는 실제 파일 이름 그대로 **./menu.ts**까지 적어야 합니다(과목 tsconfig.json의 allowImportingTsExtensions 옵션이 이를 허락합니다). 또한 작업 폴더의 package.json에는 "type": "module"이 들어 있어야 합니다(없으면 TS1295).

확인 문제

1. menu.ts에 선언된 export interface Menu⁠를 main.ts에서 type 없이 import { Menu }로 가져오면 Node 실행 때 왜 멈출까요?

힌트

타입 지우기 단계 뒤에 menu.ts와 main.ts에 각각 무엇이 남는지 생각해 보세요.

정답

타입 지우기 단계에서 menu.ts 안의 interface Menu가 사라지기 때문입니다. 반면 main.ts의 일반 import { Menu } 줄은 지워지지 않고 남아, 실행 시점에 존재하지 않는 Menu 값을 찾다가 SyntaxError로 멈춥니다.

2. 한 줄에서 타입 Menu와 값 상수 latte를 함께 가져오려면 어떻게 적나요?

힌트

1절 마지막 코드 블록의 인라인 type 표기를 살펴보세요.

정답

{ type Menu, latte }처럼 타입 이름 앞에만 type을 붙여 적습니다. 그러면 지우기 단계에서 type Menu만 지워지고 값 latte만 남습니다.

3. Node로 .ts 파일을 직접 실행하는 이 과목 환경에서 다른 파일을 가져올 때 경로 끝에 어떤 확장자를 적어야 하나요?

힌트

작업 폴더에 실제로 존재하는 파일의 확장자가 무엇인지 떠올려 보세요.

정답

실제 파일 확장자인 .ts("./menu.ts")를 적어야 합니다. 과목 tsconfig.json의 allowImportingTsExtensions 설정 덕분에 .ts 경로가 검사와 실행 양쪽에서 모두 그대로 동작합니다.

컴퓨터에서 해 보기(선택) — 점수에 들지 않습니다. 폰으로만 보고 있다면 건너뛰세요. 작업 폴더에 1절의 menu.ts와 main.ts 두 파일을 저장하고 npx tsc와 node main.ts를 차례로 실행해 보세요. 다음 레슨 선언 파일과 @types에서는 외부 환경의 타입을 알려 주는 .d.ts 파일을 배웁니다. 검사하고 돌리는 법은 내 컴퓨터에서 검사하고 돌리기에 있습니다.

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

타입스크립트 목차로