본문 바로가기
프로그래밍/Typescript

[Typescript] 모듈과 네임스페이스, 선언 병합 : 대규모 프로젝트 구조화

by iwbap 2024. 12. 24.
728x90

들어가며

타입스크립트를 사용하여 대규모 프로젝트를 개발할 때, 코드베이스를 구조화하고 모듈 간의 의존성을 명확히 관리하는 것이 중요합니다. 이번 글에서는 다음 개념을 다룹니다:

  • 모듈(Module) : 코드 재사용성과 가독성을 높이기 위한 ES 모듈과 CommonJS
  • 네임스페이스(Namespace) : 네이밍 충돌을 방지하기 위한 내부 모듈
  • 선언 병합(Declaration Merging) : 선언 확장을 통한 타입 관리

이 글을 통해 대규모 프로젝트에서도 유지보수성과 확장성을 고려한 타입스크립트 코드를 작성하는 방법을 배울 수 있습니다.


1. 모듈(Module)

1-1. ES 모듈 (Import / Export)

타입스크립트는 ES6 모듈 시스템을 기반으로 하며, 파일별로 독립적인 범위를 가집니다. export와 import를 사용해 모듈 간 의존성을 관리합니다.

파일 분리 및 export

mathUtils.ts 파일에서 함수를 정의하고 내보냅니다.

 

[typescript]

export function add(a: number, b: number): number {
  return a + b;
}

export const PI = 3.14;

 

다른 파일에서 import

다른 파일에서 모듈을 가져와 사용할 수 있습니다.

 

[typescript]

import { add, PI } from './mathUtils';

console.log(add(2, 3)); // 5
console.log(PI); // 3.14

 

기본 내보내기 (Default Export)

단일 값 또는 함수만 내보낼 경우 default 키워드를 사용할 수 있습니다.

 

[typescript]

export default function multiply(a: number, b: number): number {
  return a * b;
}

 

[typescript]

import multiply from './mathUtils';
console.log(multiply(2, 3)); // 6

 

1-2. CommonJS 모듈

Node.js 환경에서는 CommonJS 스타일의 모듈 시스템도 사용할 수 있습니다.

내보내기 : module.exports

[typescript]

module.exports = {
  add: (a: number, b: number) => a + b,
};

 

가져오기 : require

[typescript]

const mathUtils = require('./mathUtils');
console.log(mathUtils.add(2, 3)); // 5

 

2. 네임스페이스(Namespace)

2-1. 네임스페이스란?

네임스페이스는 내부 모듈로, 같은 파일 내에서 코드의 그룹화를 도와줍니다. 네임스페이스를 사용하면 글로벌 네임스페이스 오염을 방지할 수 있습니다.

 

[typescript]

namespace MathUtils {
  export const add = (a: number, b: number): number => a + b;
  export const subtract = (a: number, b: number): number => a - b;
}

console.log(MathUtils.add(2, 3)); // 5
console.log(MathUtils.subtract(5, 3)); // 2

 

2-2. 네임스페이스 병합

여러 파일에 걸쳐 네임스페이스를 분리하여 작성한 뒤 병합할 수 있습니다.

 

shapes.ts 파일

[typescript]

namespace Shapes {
  export interface Circle {
    radius: number;
  }
}

 

area.ts 파일

[typescript]

namespace Shapes {
  export function getCircleArea(circle: Circle): number {
    return Math.PI * circle.radius ** 2;
  }
}

 

네임스페이스 병합 사용

[typescript]

const circle: Shapes.Circle = { radius: 5 };
console.log(Shapes.getCircleArea(circle)); // 78.53981633974483

 

3. 선언 병합(Declaration Merging)

3-1. 기본 개념

선언 병합은 타입스크립트가 동일한 이름의 선언을 하나로 병합하는 기능입니다. 주로 인터페이스와 네임스페이스에 적용됩니다.

3-2. 인터페이스 병합

같은 이름의 인터페이스를 정의하면, 속성이 병합됩니다.

 

[typescript]

interface User {
  id: number;
}

interface User {
  name: string;
}

const user: User = { id: 1, name: 'Alice' };
console.log(user);

 

3-3. 네임스페이스와 함수 병합

네임스페이스와 함수의 선언도 병합할 수 있습니다.

 

[typescript]

function getConfig() {
  return { apiUrl: 'https://api.example.com' };
}

namespace getConfig {
  export const version = '1.0.0';
}

console.log(getConfig().apiUrl); // 'https://api.example.com'
console.log(getConfig.version); // '1.0.0'

 

4. 실용 예제 : 선언 파일과 외부 라이브러리 타입 정의

문제

외부 라이브러리를 사용할 때 타입 정의가 없으면 타입스크립트의 타입 체크를 사용할 수 없습니다. 이를 해결하기 위해 선언 파일을 작성하거나 @types 패키지를 설치합니다.

코드

선언 파일 작성

mathUtils.js (외부 자바스크립트 라이브러리)

[javascript]

function add(a, b) {
  return a + b;
}
module.exports = { add };

 

mathUtils.d.ts (선언 파일)

[typescript]

declare module 'mathUtils' {
  export function add(a: number, b: number): number;
}

 

사용

[typescript]

import { add } from 'mathUtils';
console.log(add(2, 3)); // 5

 

DefinitelyTyped 활용

많은 라이브러리는 @types 패키지를 통해 타입 정의를 제공합니다. 예를 들어, lodash를 설치하려면 다음 명령어를 사용합니다.

 

[bash]

npm install lodash @types/lodash

 

 

마무리

이번 글에서는 타입스크립트에서 모듈, 네임스페이스, 선언 병합을 사용하는 방법을 배웠습니다. 이러한 기능들은 대규모 프로젝트에서 코드 충돌을 방지하고, 유지보수성을 높이며, 외부 라이브러리와의 통합을 원활하게 만듭니다.

다음 단계에서는 빌드, 린팅, 테스트, 프레임워크 연동을 학습하여 실무 환경에서 타입스크립트를 효과적으로 사용하는 방법을 알아보겠습니다.

728x90