Skip to content

Latest commit

Β 

History

History
844 lines (614 loc) Β· 28.6 KB

Modules.md

File metadata and controls

844 lines (614 loc) Β· 28.6 KB

μš©μ–΄μ— λŒ€ν•œ μ°Έκ³  사항: TypeScript 1.5μ—μ„œλŠ” λͺ…칭이 λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
"λ‚΄λΆ€(Internal) λͺ¨λ“ˆ"은 이제 "λ„€μž„μŠ€νŽ˜μ΄μŠ€"μž…λ‹ˆλ‹€.
"μ™ΈλΆ€(External) λͺ¨λ“ˆ"은 이제 ECMAScript 2015의 μš©μ–΄μ— 맞게 κ°„λ‹¨νžˆ "λͺ¨λ“ˆ"μž…λ‹ˆλ‹€ (즉 λͺ¨λ“ˆ X { λŠ” ν˜„μž¬ μ„ ν˜Έλ˜λŠ” λ„€μž„μŠ€νŽ˜μ΄μŠ€ X { 와 λ™μΌν•©λ‹ˆλ‹€).

μ†Œκ°œ

ECMAScript 2015λΆ€ν„° JavaScriptμ—λŠ” λͺ¨λ“ˆ κ°œλ…μ΄ μžˆμŠ΅λ‹ˆλ‹€. TypeScriptλŠ” 이 κ°œλ…μ„ κ³΅μœ ν•©λ‹ˆλ‹€.

λͺ¨λ“ˆμ€ μ „μ—­ μŠ€μ½”ν”„κ°€ μ•„λ‹Œ 자체 μŠ€μ½”ν”„ λ‚΄μ—μ„œ μ‹€ν–‰λ©λ‹ˆλ‹€.
μ΄λŠ” export ν˜•μ‹ 쀑 ν•˜λ‚˜λ₯Ό μ‚¬μš©ν•˜μ—¬ λͺ…μ‹œμ μœΌλ‘œ 내보내지 μ•ŠλŠ” ν•œ λͺ¨λ“ˆμ— μ„ μ–Έλœ λ³€μˆ˜, ν•¨μˆ˜, 클래슀 등이 λͺ¨λ“ˆ 외뢀에 보이지 μ•ŠλŠ”λ‹€λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€.
λ°˜λŒ€λ‘œ λ‹€λ₯Έ λͺ¨λ“ˆμ—μ„œ 내보낸 λ³€μˆ˜, ν•¨μˆ˜, 클래슀, μΈν„°νŽ˜μ΄μŠ€ 등을 μ‚¬μš©ν•˜λ €λ©΄ import ν˜•μ‹ 쀑 ν•˜λ‚˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 가져와야 ν•©λ‹ˆλ‹€.

λͺ¨λ“ˆμ€ μ„ μ–Έμ μž…λ‹ˆλ‹€. λͺ¨λ“ˆ κ°„μ˜ κ΄€κ³„λŠ” 파일 μˆ˜μ€€μ—μ„œ imports 및 exports μΈ‘λ©΄μ—μ„œ μ§€μ •λ©λ‹ˆλ‹€.

λͺ¨λ“ˆμ€ λͺ¨λ“ˆ λ‘œλ”λ₯Ό μ‚¬μš©ν•˜μ—¬ 또 λ‹€λ₯Έ λͺ¨λ“ˆμ„ import ν•©λ‹ˆλ‹€.
λŸ°νƒ€μž„μ‹œ λͺ¨λ“ˆ λ‘œλ”λŠ” λͺ¨λ“ˆμ„ μ‹€ν–‰ν•˜κΈ° 전에 λͺ¨λ“ˆμ˜ λͺ¨λ“  μ˜μ‘΄μ„±μ„ μ°Ύκ³  μ‹€ν–‰ν•©λ‹ˆλ‹€.
JavaScriptμ—μ„œ μ‚¬μš©λ˜λŠ” 잘 μ•Œλ €μ§„ λͺ¨λ“ˆ λ‘œλ”λŠ” Node.js의 CommonJSλͺ¨λ“ˆ λ‘œλ”μ΄λ©° μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 경우 require.jsμž…λ‹ˆλ‹€.

TypeScriptμ—μ„œλŠ” ECMAScript 2015와 λ§ˆμ°¬κ°€μ§€λ‘œ μ΅œμƒμœ„ import λ˜λŠ” exportκ°€ ν¬ν•¨λœ νŒŒμΌμ„ λͺ¨λ“ˆλ‘œ κ°„μ£Όν•©λ‹ˆλ‹€.

내보내기 (Export)

내보내기 μ„ μ–Έ (Exporting a declaration)

λ³€μˆ˜, ν•¨μˆ˜, 클래슀, νƒ€μž… 별칭(alias) λ˜λŠ” μΈν„°νŽ˜μ΄μŠ€μ™€ 같은 선언문은 export ν‚€μ›Œλ“œλ₯Ό μΆ”κ°€ν•˜μ—¬ 내보낼 수 μžˆμŠ΅λ‹ˆλ‹€.

Validation.ts
export interface StringValidator {
    isAcceptable(s: string): boolean;
}
ZipCodeValidator.ts
export const numberRegexp = /^[0-9]+$/;

export class ZipCodeValidator implements StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}

내보내기 λ¬Έ (Export statements)

Export 문은 μ‚¬μš©μžλ₯Ό μœ„ν•΄ Export의 이름을 λ³€κ²½ν•΄μ•Ό ν•˜λŠ” κ²½μš°μ— μœ μš©ν•˜λ―€λ‘œ μœ„μ˜ 예제λ₯Ό λ‹€μŒκ³Ό 같이 μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

class ZipCodeValidator implements StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}
export { ZipCodeValidator };
export { ZipCodeValidator as mainValidator };

λ‹€μ‹œ 내보내기 (Re-exports)

μ’…μ’… λͺ¨λ“ˆμ€ λ‹€λ₯Έ λͺ¨λ“ˆμ„ ν™•μž₯ν•˜κ³  일뢀 κΈ°λŠ₯을 λΆ€λΆ„μ μœΌλ‘œ λ…ΈμΆœν•©λ‹ˆλ‹€.
λ‹€μ‹œ 내보내기(re-export)λŠ” 둜컬둜 importν•˜κ±°λ‚˜ 둜컬 λ³€μˆ˜λ₯Ό λ„μž…ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

ParseIntBasedZipCodeValidator.ts
export class ParseIntBasedZipCodeValidator {
    isAcceptable(s: string) {
        return s.length === 5 && parseInt(s).toString() === s;
    }
}

// 원본 validator λ‚΄λ³΄λ‚΄μ§€λ§Œ 이름을 λ³€κ²½ν•©λ‹ˆλ‹€
export {ZipCodeValidator as RegExpBasedZipCodeValidator} from "./ZipCodeValidator";

μ„ νƒμ μœΌλ‘œ λͺ¨λ“ˆμ€ ν•˜λ‚˜ μ΄μƒμ˜ λͺ¨λ“ˆμ„ 감싸고 export * from "module" ꡬ문을 μ‚¬μš©ν•˜μ—¬ λͺ¨λ“  exportλ₯Ό κ²°ν•©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

AllValidators.ts
export * from "./StringValidator"; // exports interface 'StringValidator'
export * from "./LettersOnlyValidator"; // exports class 'LettersOnlyValidator'
export * from "./ZipCodeValidator";  // exports class 'ZipCodeValidator'

Import

importλŠ” λͺ¨λ“ˆμ—μ„œ export 만큼 μ‰½μŠ΅λ‹ˆλ‹€.
export 선언을 κ°€μ Έμ˜€λ €λ©΄ μ•„λž˜μ˜ import ν˜•μ‹ 쀑 ν•˜λ‚˜λ₯Ό μ‚¬μš©ν•˜μ‹­μ‹œμ˜€.

λͺ¨λ“ˆμ—μ„œ 단일 내보내기 κ°€μ Έμ˜€κΈ° (Import a single export from a module)

import { ZipCodeValidator } from "./ZipCodeValidator";

let myValidator = new ZipCodeValidator();

imports 이름을 λ³€κ²½ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

import { ZipCodeValidator as ZCV } from "./ZipCodeValidator";
let myValidator = new ZCV();

전체 λͺ¨λ“ˆμ„ 단일 λ³€μˆ˜λ‘œ κ°€μ Έμ˜€κ³  이λ₯Ό μ‚¬μš©ν•˜μ—¬ λͺ¨λ“ˆ 내보내기에 μ ‘κ·Όν•˜κΈ° (Import the entire module into a single variable, and use it to access the module exports)

import * as validator from "./ZipCodeValidator";
let myValidator = new validator.ZipCodeValidator();

λΆ€μˆ˜ νš¨κ³Όμ— λŒ€ν•œ λͺ¨λ“ˆλ§Œ κ°€μ Έμ˜€κΈ° (Import a module for side-effects only)

ꢌμž₯λ˜μ§€λŠ” μ•Šμ§€λ§Œ 일뢀 λͺ¨λ“ˆμ€ λ‹€λ₯Έ λͺ¨λ“ˆμ—μ„œ μ‚¬μš©ν•  수 μžˆλŠ” κΈ€λ‘œλ²Œ μƒνƒœλ₯Ό μ„€μ •ν•©λ‹ˆλ‹€.
μ΄λŸ¬ν•œ λͺ¨λ“ˆμ—λŠ” μ–΄λ– ν•œ exports도 μ—†κ±°λ‚˜ μ‚¬μš©μžκ°€ ν•΄λ‹Ή exports에 관심이 없을 수 μžˆμŠ΅λ‹ˆλ‹€.

μ΄λŸ¬ν•œ λͺ¨λ“ˆμ„ κ°€μ Έμ˜€λ €λ©΄ λ‹€μŒμ„ μ‚¬μš©ν•©λ‹ˆλ‹€:

import "./my-module.js";

κΈ°λ³Έ 내보내기 (Default exports)

각 λͺ¨λ“ˆμ€ μ„ νƒμ μœΌλ‘œ default exportλ₯Ό 내보낼 수 μžˆμŠ΅λ‹ˆλ‹€.
Default exportsλŠ” default ν‚€μ›Œλ“œλ‘œ ν‘œμ‹œλ©λ‹ˆλ‹€. λͺ¨λ“ˆλ³„ default exportsλŠ” ν•˜λ‚˜λ§Œ κ°€λŠ₯ν•©λ‹ˆλ‹€.
default exportsλŠ” λ‹€λ₯Έ import ν˜•μ‹μ„ μ‚¬μš©ν•˜μ—¬ κ°€μ Έμ˜΅λ‹ˆλ‹€.

default exportsλŠ” 정말 νŽΈλ¦¬ν•©λ‹ˆλ‹€.
예λ₯Ό λ“€μ–΄ JQuery 같은 λΌμ΄λΈŒλŸ¬λ¦¬μ—λŠ” default export인 jQuery λ˜λŠ” $κ°€ μžˆμ„ 수 있으며 이λ₯Ό $λ‚˜ jQueryλΌλŠ” μ΄λ¦„μœΌλ‘œλ„ κ°€μ Έμ˜¬ 수 μžˆμŠ΅λ‹ˆλ‹€.

JQuery.d.ts
declare let $: JQuery;
export default $;
App.ts
import $ from "JQuery";

$("button.continue").html( "Next Step..." );

클래슀 및 ν•¨μˆ˜ 선언은 default exports둜 직접 μž‘μ„±λ  수 μžˆμŠ΅λ‹ˆλ‹€.
Default export ν΄λž˜μŠ€μ™€ ν•¨μˆ˜ μ„ μ–Έ 넀이밍은 μ„ νƒμ μž…λ‹ˆλ‹€.

ZipCodeValidator.ts
export default class ZipCodeValidator {
    static numberRegexp = /^[0-9]+$/;
    isAcceptable(s: string) {
        return s.length === 5 && ZipCodeValidator.numberRegexp.test(s);
    }
}
Test.ts
import validator from "./ZipCodeValidator";

let myValidator = new validator();

λ˜λŠ”

StaticZipCodeValidator.ts
const numberRegexp = /^[0-9]+$/;

export default function (s: string) {
    return s.length === 5 && numberRegexp.test(s);
}
Test.ts
import validate from "./StaticZipCodeValidator";

let strings = ["Hello", "98052", "101"];

// ν•¨μˆ˜ μœ νš¨μ„± 검사 μ‚¬μš©
strings.forEach(s => {
  console.log(`"${s}" ${validate(s) ? " matches" : " does not match"}`);
});

default exportsλŠ” κ°’ 일 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€:

OneTwoThree.ts
export default "123";
Log.ts
import num from "./OneTwoThree";

console.log(num); // "123"

export = and import = require()

CommonJS와 AMD λͺ¨λ‘ 일반적으둜 λͺ¨λ“ˆμ˜ λͺ¨λ“  exportsλ₯Ό ν¬ν•¨ν•˜λŠ” exports 객체 κ°œλ…μ„ 가지고 μžˆμŠ΅λ‹ˆλ‹€.

λ˜ν•œ exports 객체λ₯Ό μ»€μŠ€ν…€ 단일 객체둜 λŒ€μ²΄ν•˜λŠ” 것을 μ§€μ›ν•©λ‹ˆλ‹€.
Default exportsλŠ”μ΄ λ™μž‘μ„ λŒ€μ‹ ν•˜λŠ” 역할을 ν•©λ‹ˆλ‹€.
κ·ΈλŸ¬λ‚˜ κ·Έ λ‘˜μ€ ν˜Έν™˜λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
TypeScriptλŠ” 기쑴의 CommonJS와 AMD μ›Œν¬ν”Œλ‘œμš°λ₯Ό λͺ¨λΈλ§ν•˜κΈ° μœ„ν•΄ export =λ₯Ό μ§€μ›ν•©λ‹ˆλ‹€.

export = ꡬ문은 λͺ¨λ“ˆμ—μ„œ export된 단일 객체λ₯Ό μ§€μ •ν•©λ‹ˆλ‹€. 클래슀, μΈν„°νŽ˜μ΄μŠ€, λ„€μž„μŠ€νŽ˜μ΄μŠ€, ν•¨μˆ˜ λ˜λŠ” μ—΄κ±°ν˜•μ΄ 될 수 μžˆμŠ΅λ‹ˆλ‹€.

export =λ₯Ό μ‚¬μš©ν•˜μ—¬ λͺ¨λ“ˆμ„ import ν•  λ•Œ λͺ¨λ“ˆμ„ import ν•˜κΈ° μœ„ν•΄ TypeScript에 νŠΉμ •ν•œ import module = require("module")을 μ‚¬μš©ν•΄μ•Όν•©λ‹ˆλ‹€.

ZipCodeValidator.ts
let numberRegexp = /^[0-9]+$/;
class ZipCodeValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}
export = ZipCodeValidator;
Test.ts
import zip = require("./ZipCodeValidator");

// μ‹œν—˜μš© μƒ˜ν”Œ
let strings = ["Hello", "98052", "101"];

// μ‚¬μš©ν•  Validators
let validator = new zip();

// 각 λ¬Έμžμ—΄μ΄ 각 Validatorλ₯Ό ν†΅κ³Όν–ˆλŠ”μ§€ μ—¬λΆ€λ₯Ό λ³΄μ—¬μ€λ‹ˆλ‹€.
strings.forEach(s => {
  console.log(`"${ s }" - ${ validator.isAcceptable(s) ? "matches" : "does not match" }`);
});

λͺ¨λ“ˆμ„ μœ„ν•œ μ½”λ“œ 생성 (Code Generation for Modules)

μ»΄νŒŒμΌμ‹œ μ§€μ •λœ λͺ¨λ“ˆ λŒ€μƒμ— 따라 μ»΄νŒŒμΌλŸ¬λŠ” Node.js (CommonJS), require.js (AMD), UMD, SystemJS λ˜λŠ” ECMAScript 2015 λ„€μ΄ν‹°λΈŒ λͺ¨λ“ˆ (ES6)에 μ μ ˆν•œ μ½”λ“œλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
μƒμ„±λœ μ½”λ“œμ—μ„œ define, require 및 register ν˜ΈμΆœμ— λŒ€ν•œ μžμ„Έν•œ μ •λ³΄λŠ” 각 λͺ¨λ“ˆ λ‘œλ”μ— λŒ€ν•œ λ¬Έμ„œλ₯Ό μ°Έμ‘°ν•˜μ„Έμš”.

이 κ°„λ‹¨ν•œ μ˜ˆμ œλŠ” import 및 export 쀑에 μ‚¬μš©λ˜λŠ” 이름이 λͺ¨λ“ˆ λ‘œλ”© μ½”λ“œλ‘œ μ–΄λ–»κ²Œ λ³€ν™˜λ˜λŠ”μ§€ λ³΄μ—¬μ€λ‹ˆλ‹€.

SimpleModule.ts
import m = require("mod");
export let t = m.something + 1;
AMD / RequireJS SimpleModule.js
define(["require", "exports", "./mod"], function (require, exports, mod_1) {
    exports.t = mod_1.something + 1;
});
CommonJS / Node SimpleModule.js
var mod_1 = require("./mod");
exports.t = mod_1.something + 1;
UMD SimpleModule.js
(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports); if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "./mod"], factory);
    }
})(function (require, exports) {
    var mod_1 = require("./mod");
    exports.t = mod_1.something + 1;
});
System SimpleModule.js
System.register(["./mod"], function(exports_1) {
    var mod_1;
    var t;
    return {
        setters:[
            function (mod_1_1) {
                mod_1 = mod_1_1;
            }],
        execute: function() {
            exports_1("t", t = mod_1.something + 1);
        }
    }
});
Native ECMAScript 2015 modules SimpleModule.js
import { something } from "./mod";
export var t = something + 1;

κ°„λ‹¨ν•œ 예제 (Simple Example)

μ•„λž˜μ—μ„œλŠ” 각 λͺ¨λ“ˆμ—μ„œ 이름이 μ§€μ •λœ 단일 export만 내보내도둝 이전 μ˜ˆμ œμ— μ‚¬μš©λœ Validator κ΅¬ν˜„μ„ ν†΅ν•©ν–ˆμŠ΅λ‹ˆλ‹€.

μ»΄νŒŒμΌν•˜λ €λ©΄ μ»€λ§¨λ“œ 라인에 λͺ¨λ“ˆ λŒ€μƒμ„ 지정해야 ν•©λ‹ˆλ‹€.
Node.jsλŠ” --module commonjsλ₯Ό μ‚¬μš©ν•˜μ„Έμš”.
require.js의 경우 --module amdλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄:

tsc --module commonjs Test.ts

μ»΄νŒŒμΌμ‹œ 각 λͺ¨λ“ˆμ€ λ³„λ„μ˜ .js 파일이 λ©λ‹ˆλ‹€.
μ°Έμ‘° νƒœκ·Έμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ μ»΄νŒŒμΌλŸ¬λŠ” 의쑴된 νŒŒμΌλ“€μ„ μ»΄νŒŒμΌν•˜κΈ° μœ„ν•΄ import 문을 λ”°λ¦…λ‹ˆλ‹€.

Validation.ts
export interface StringValidator {
    isAcceptable(s: string): boolean;
}
LettersOnlyValidator.ts
import { StringValidator } from "./Validation";

const lettersRegexp = /^[A-Za-z]+$/;

export class LettersOnlyValidator implements StringValidator {
    isAcceptable(s: string) {
        return lettersRegexp.test(s);
    }
}
ZipCodeValidator.ts
import { StringValidator } from "./Validation";

const numberRegexp = /^[0-9]+$/;

export class ZipCodeValidator implements StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}
Test.ts
import { StringValidator } from "./Validation";
import { ZipCodeValidator } from "./ZipCodeValidator";
import { LettersOnlyValidator } from "./LettersOnlyValidator";

// μ‹œν—˜μš© μƒ˜ν”Œ
let strings = ["Hello", "98052", "101"];

// μ‚¬μš©ν•  Validators
let validators: { [s: string]: StringValidator; } = {};
validators["ZIP code"] = new ZipCodeValidator();
validators["Letters only"] = new LettersOnlyValidator();

// 각 λ¬Έμžμ—΄μ΄ 각 Validatorλ₯Ό ν†΅κ³Όν–ˆλŠ”μ§€ μ—¬λΆ€λ₯Ό λ³΄μ—¬μ€λ‹ˆλ‹€.
strings.forEach(s => {
    for (let name in validators) {
        console.log(`"${ s }" - ${ validators[name].isAcceptable(s) ? "matches" : "does not match" } ${ name }`);
    }
});

선택적 λͺ¨λ“ˆ λ‘œλ”©κ³Ό 기타 κ³ κΈ‰ λ‘œλ”© μ‹œλ‚˜λ¦¬μ˜€ (Optional Module Loading and Other Advanced Loading Scenarios)

상황에 따라 일뢀 μ‘°κ±΄μ—μ„œλ§Œ λͺ¨λ“ˆμ„ λ‘œλ“œν•  수 μžˆμŠ΅λ‹ˆλ‹€.
TypeScriptμ—μ„œλŠ” μ•„λž˜μ˜ νŒ¨ν„΄μ„ 톡해 λ‹€λ₯Έ κ³ κΈ‰ λ‘œλ“œ μ‹œλ‚˜λ¦¬μ˜€λ₯Ό κ΅¬ν˜„ν•˜μ—¬ νƒ€μž… μ•ˆμ „μ„±μ„ μžƒμ§€ μ•Šκ³  λͺ¨λ“ˆ λ‘œλ”λ₯Ό 직접 ν˜ΈμΆœν•  수 μžˆμŠ΅λ‹ˆλ‹€.
μ»΄νŒŒμΌλŸ¬λŠ” 각 λͺ¨λ“ˆμ΄ 방좜된 JavaScriptμ—μ„œ μ‚¬μš©λ˜λŠ”μ§€ μ—¬λΆ€λ₯Ό κ°μ§€ν•©λ‹ˆλ‹€.
λͺ¨λ“ˆ μ‹λ³„μžκ°€ νƒ€μž… μ–΄λ…Έν…Œμ΄μ…˜μ˜ μΌλΆ€λ‘œλ§Œ μ‚¬μš©λ˜κ³  ν‘œν˜„μ‹μœΌλ‘œ μ‚¬μš©λ˜μ§€ μ•ŠμœΌλ©΄ ν•΄λ‹Ή λͺ¨λ“ˆμ— λŒ€ν•œ require 호좜이 λ°©μΆœν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” μ°Έμ‘°λ₯Ό μ œκ±°ν•˜λ©΄ μ„±λŠ₯이 μ΅œμ ν™”λ˜κ³  ν•΄λ‹Ή λͺ¨λ“ˆμ„ μ„ νƒμ μœΌλ‘œ λ‘œλ“œν•  수 μžˆμŠ΅λ‹ˆλ‹€.

이 νŒ¨ν„΄μ˜ 핡심 μ•„μ΄λ””μ–΄λŠ” import id = require("...")문이 λͺ¨λ“ˆμ— μ˜ν•΄ λ…ΈμΆœλœ νƒ€μž…μ— μ ‘κ·Όν•  수 μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.
λͺ¨λ“ˆ λ‘œλ”λŠ” μ•„λž˜μ˜ if λΈ”λ‘μ²˜λŸΌ λ™μ μœΌλ‘œ (requireλ₯Ό 톡해) ν˜ΈμΆœλ©λ‹ˆλ‹€.
μ΄λŠ” μ°Έμ‘° μƒλž΅ μ΅œμ ν™”κ°€ ν™œμš©λ˜μ–΄ λͺ¨λ“ˆμ΄ ν•„μš”ν•œ κ²½μš°μ—λ§Œ λ‘œλ“œλ©λ‹ˆλ‹€.
이 νŒ¨ν„΄μ΄ μž‘λ™ν•˜λ €λ©΄ importλ₯Ό 톡해 μ •μ˜λœ symbol이 νƒ€μž… μœ„μΉ˜μ—μ„œλ§Œ μ‚¬μš©λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€(즉 JavaScript둜 방좜될 수 μžˆλŠ” μœ„μΉ˜μ— μ ˆλŒ€ μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€).

νƒ€μž… μ•ˆμ „μ„±μ„ μœ μ§€ν•˜κΈ° μœ„ν•΄ typeof ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
typeof ν‚€μ›Œλ“œλŠ” νƒ€μž…μ˜ μœ„μΉ˜μ—μ„œ μ‚¬μš©λ  λ•Œ κ°’μ˜ νƒ€μž…μ„ μƒμ„±ν•˜λ©° 이 경우 λͺ¨λ“ˆμ˜ νƒ€μž…μ΄ λ©λ‹ˆλ‹€.

Node.js의 동적 λͺ¨λ“ˆ λ‘œλ”© (Dynamic Module Loading in Node.js)
declare function require(moduleName: string): any;

import { ZipCodeValidator as Zip } from "./ZipCodeValidator";

if (needZipValidation) {
    let ZipCodeValidator: typeof Zip = require("./ZipCodeValidator");
    let validator = new ZipCodeValidator();
    if (validator.isAcceptable("...")) { /* ... */ }
}
μƒ˜ν”Œ: require.js의 동적 λͺ¨λ“ˆ λ‘œλ”© (Dynamic Module Loading in require.js)
declare function require(moduleNames: string[], onLoad: (...args: any[]) => void): void;

import * as Zip from "./ZipCodeValidator";

if (needZipValidation) {
    require(["./ZipCodeValidator"], (ZipCodeValidator: typeof Zip) => {
        let validator = new ZipCodeValidator.ZipCodeValidator();
        if (validator.isAcceptable("...")) { /* ... */ }
    });
}
μƒ˜ν”Œ: System.js의 동적 λͺ¨λ“ˆ λ‘œλ”© (Dynamic Module Loading in System.js)
declare const System: any;

import { ZipCodeValidator as Zip } from "./ZipCodeValidator";

if (needZipValidation) {
    System.import("./ZipCodeValidator").then((ZipCodeValidator: typeof Zip) => {
        var x = new ZipCodeValidator();
        if (x.isAcceptable("...")) { /* ... */ }
    });
}

λ‹€λ₯Έ JavaScript 라이브러리 μ‚¬μš© (Working with Other JavaScript Libraries)

TypeScript둜 μž‘μ„±λ˜μ§€ μ•Šμ€ 라이브러리의 ν˜•νƒœμ„ μ„€λͺ…ν•˜λ €λ©΄ λΌμ΄λΈŒλŸ¬λ¦¬κ°€ λ‚˜νƒ€λ‚΄λŠ” APIλ₯Ό μ„ μ–Έν•΄μ•Ό ν•©λ‹ˆλ‹€.

κ΅¬ν˜„μ„ "ambient"으둜 μ •μ˜ν•˜μ§€ μ•ŠλŠ” 선언이라고 ν•˜λ©° 일반적으둜 이듀은 .d.ts νŒŒμΌμ— μ •μ˜λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.
C/C++에 μ΅μˆ™ν•˜λ‹€λ©΄ 이것듀을 .h파일둜 생각할 수 μžˆμ„ κ²ƒμž…λ‹ˆλ‹€.

λͺ‡ 가지 예λ₯Ό λ“€μ–΄λ³΄κ² μŠ΅λ‹ˆλ‹€

Ambient Modules

Node.jsμ—μ„œ λŒ€λΆ€λΆ„μ˜ μž‘μ—…μ€ ν•˜λ‚˜ μ΄μƒμ˜ λͺ¨λ“ˆμ„ λ‘œλ“œν•˜μ—¬ μˆ˜ν–‰λ©λ‹ˆλ‹€.
각 λͺ¨λ“ˆμ„ .d.ts νŒŒμΌμ— μ΅œμƒμœ„ μˆ˜μ€€μ˜ 내보내기 μ„ μ–ΈμœΌλ‘œ μ •μ˜ν•  수 μžˆμ§€λ§Œ 더 넓은 .d.ts 파일둜 μž‘μ„±ν•˜λŠ” 것이 더 νŽΈλ¦¬ν•©λ‹ˆλ‹€.
κ·Έλ ‡κ²Œν•˜κΈ° μœ„ν•΄μ„œ ambient λ„€μž„μŠ€νŽ˜μ΄μŠ€μ™€ λΉ„μŠ·ν•œ ꡬ쑰λ₯Ό μ‚¬μš©ν•˜μ§€λ§Œ λ‚˜μ€‘μ— import ν•  수 μžˆλŠ” λͺ¨λ“ˆμ˜ module ν‚€μ›Œλ“œμ™€ λ”°μ˜΄ν‘œ 뢙은 이름을 μ‚¬μš©ν•©λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄:

node.d.ts (simplified excerpt)
declare module "url" {
    export interface Url {
        protocol?: string;
        hostname?: string;
        pathname?: string;
    }

    export function parse(urlStr: string, parseQueryString?, slashesDenoteHost?): Url;
}

declare module "path" {
    export function normalize(p: string): string;
    export function join(...paths: any[]): string;
    export var sep: string;
}

이제 /// <reference> node.d.ts λ₯Ό λ§Œλ“€ 수 있고 import url = require("url"); λ˜λŠ” import * as URL from "url" λ₯Ό μ‚¬μš©ν•˜μ—¬ λͺ¨λ“ˆμ„ μ μž¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

/// <reference path="node.d.ts"/>
import * as URL from "url";
let myUrl = URL.parse("http://www.typescriptlang.org");

Shorthand ambient modules

μƒˆλ‘œμš΄ λͺ¨λ“ˆμ„ μ‚¬μš©ν•˜κΈ° 전에 선언을 μž‘μ„±ν•˜λŠ” μ‹œκ°„μ„ λ‚΄κ³  싢지 μ•Šλ‹€λ©΄ shorthand 선언을 μ‚¬μš©ν•˜μ—¬ λΉ λ₯΄κ²Œ μ‹œμž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

declarations.d.ts
declare module "hot-new-module";

shorthand λͺ¨λ“ˆμ˜ λͺ¨λ“  importsλŠ” any νƒ€μž…μ„ κ°€μ§‘λ‹ˆλ‹€.

import x, {y} from "hot-new-module";
x(y);

Wildcard module declarations

SystemJS 및 AMD 같은 일뢀 λͺ¨λ“ˆ λ‘œλ”λ“€μ€ JavaScriptκ°€ μ•„λ‹Œ 컨텐츠λ₯Ό import ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
일반적으둜 νŠΉλ³„ν•œ λ‘œλ“œμ˜ μ˜λ―Έλ‘ μ„ λ‚˜νƒ€λ‚΄λŠ” 접두사 λ˜λŠ” 접미사λ₯Ό μ‚¬μš©ν•œλ‹€.
μ΄λŸ¬ν•œ 경우λ₯Ό 닀루기 μœ„ν•΄ Wildcard λͺ¨λ“ˆ 선언을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

declare module "*!text" {
    const content: string;
    export default content;
}
// μΌλΆ€λŠ” κ·Έ λ°˜λŒ€μ˜ 방법을 μ‚¬μš©ν•©λ‹ˆλ‹€.
declare module "json!*" {
    const value: any;
    export default value;
}

이제 "*!text" λ˜λŠ” "json!*" κ³Ό μΌμΉ˜ν•˜λŠ” 것을 import ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

import fileContent from "./xyz.txt!text";
import data from "json!http://example.com/data.json";
console.log(data, fileContent);

UMD modules

일뢀 λΌμ΄λΈŒλŸ¬λ¦¬λŠ” λ§Žμ€ λͺ¨λ“ˆ λ‘œλ”μ—μ„œ μ‚¬μš©ν•˜λ„λ‘ μ„€κ³„λ˜μ—ˆκ±°λ‚˜ λͺ¨λ“ˆ λ‘œλ“œκ°€ μ—†μŠ΅λ‹ˆλ‹€ (κΈ€λ‘œλ²Œ λ³€μˆ˜).
μ΄λŸ¬ν•œ λͺ¨λ“ˆμ„ UMD λͺ¨λ“ˆμ΄λΌκ³  ν•©λ‹ˆλ‹€.
μ΄λŸ¬ν•œ λΌμ΄λΈŒλŸ¬λ¦¬λŠ” import λ˜λŠ” κΈ€λ‘œλ²Œ λ³€μˆ˜λ₯Ό 톡해 μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄:

math-lib.d.ts
export function isPrime(x: number): boolean;
export as namespace mathLib;

그러면 라이브러리λ₯Ό λͺ¨λ“ˆμ—μ„œ import둜 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

import { isPrime } from "math-lib";
isPrime(2);
mathLib.isPrime(2); // 였λ₯˜: λͺ¨λ“ˆ λ‚΄λΆ€μ—μ„œ μ „μ—­ μ •μ˜λ₯Ό ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

κΈ€λ‘œλ²Œ λ³€μˆ˜λ‘œ μ‚¬μš©ν•  μˆ˜λ„ μžˆμ§€λ§Œ 슀크립트 λ‚΄λΆ€μ—μ„œλ§Œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
(μŠ€ν¬λ¦½νŠΈλŠ” imports λ˜λŠ” exportsκ°€ μ—†λŠ” νŒŒμΌμž…λ‹ˆλ‹€)

mathLib.isPrime(2);

λͺ¨λ“ˆ ꡬ쑰화λ₯Ό μœ„ν•œ κ°€μ΄λ“œ (Guidance for structuring modules)

μ΅œμƒμœ„ λ ˆλ²¨μ— κ°€κΉκ²Œ 내보내기 (Export as close to top-level as possible)

λͺ¨λ“ˆμ˜ μ‚¬μš©μžλ“€μ€ export ν•œ 것듀을 μ‚¬μš©ν•  λ•Œ κ°€λŠ₯ν•œ ν•œ 마찰이 적어야 ν•©λ‹ˆλ‹€.
λ„ˆλ¬΄ λ§Žμ€ μ€‘μ²©μ˜ λ ˆλ²¨μ„ μΆ”κ°€ν•˜λŠ” 것은 닀루기 νž˜λ“€κΈ° λ•Œλ¬Έμ— ꡬ쑰화 방법에 λŒ€ν•΄ μ‹ μ€‘νžˆ μƒκ°ν•˜μ„Έμš”.

λͺ¨λ“ˆμ—μ„œ λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό export ν•˜λŠ” 것은 쀑첩 계측을 λ„ˆλ¬΄ 많이 μΆ”κ°€ν•˜λŠ” μ˜ˆμž…λ‹ˆλ‹€.
λ„€μž„μŠ€νŽ˜μ΄μŠ€κ°€ ν•„μš”ν• λ•Œλ„ μžˆμ§€λ§Œ λͺ¨λ“ˆμ„ μ‚¬μš©ν•  λ•ŒλŠ” 좔가적인 레벨의 κ°„μ ‘ μ°Έμ‘°λ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€.
μ΄λŠ” μ‚¬μš©μžμ—κ²Œ 재빠λ₯΄κ²Œ 고톡이 될 수 있으며 일반적으둜 λΆˆν•„μš”ν•©λ‹ˆλ‹€.

export 클래슀의 정적 λ©”μ„œλ“œμ—λ„ λΉ„μŠ·ν•œ λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€ - 클래슀 자체적으둜 쀑첩 계측을 μΆ”κ°€ν•©λ‹ˆλ‹€.
ν‘œν˜„μ΄λ‚˜ μ˜λ„κ°€ λͺ…ν™•ν•˜κ³  μœ μš©ν•œ λ°©μ‹μœΌλ‘œ μ¦κ°€ν•˜μ§€ μ•ŠλŠ” ν•œ κ°„λ‹¨ν•œ 헬퍼 ν•¨μˆ˜λ₯Ό λ‚΄λ³΄λ‚΄λŠ” 것을 κ³ λ €ν•˜μ„Έμš”.

단일 class λ˜λŠ” function만 exportν•˜λŠ” 경우 export defaultλ₯Ό μ‚¬μš©ν•˜μ„Έμš” (If you're only exporting a single class or function, use export default)

"μ΅œμƒμœ„ λ ˆλ²¨μ— κ°€κΉκ²Œ 내보내기"κ°€ λͺ¨λ“ˆ μ‚¬μš©μžμ˜ λ§ˆμ°°μ„ μ€„μ΄λŠ” κ²ƒμ²˜λŸΌ default exportλ₯Ό λ„μž…ν•˜λŠ” 것도 λ§ˆμ°¬κ°€μ§€μž…λ‹ˆλ‹€.
λͺ¨λ“ˆμ˜ μ£Όμš” λͺ©μ μ΄ ν•˜λ‚˜μ˜ νŠΉμ • exportλ₯Ό μ €μž₯ν•˜λŠ” 것이라면 이λ₯Ό default export둜 export ν•˜λŠ” 것을 κ³ λ €ν•΄μ•Ό ν•©λ‹ˆλ‹€.
μ΄λ ‡κ²Œ ν•˜λ©΄ importingλ₯Ό μ‚¬μš©ν•˜λ©° μ‹€μ œλ‘œ importλ₯Ό 더 μ‰½κ²Œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄:

MyClass.ts

export default class SomeType {
  constructor() { ... }
}

MyFunc.ts

export default function getThing() { return "thing"; }

Consumer.ts

import t from "./MyClass";
import f from "./MyFunc";
let x = new t();
console.log(f());

μ΄λŠ” μ‚¬μš©μžλ₯Ό μœ„ν•œ 졜적의 μ„ νƒμž…λ‹ˆλ‹€.
νƒ€μž…μ˜ 이름을 μ›ν•˜λŠ” λŒ€λ‘œ 지을 수 있으며(이 경우 t) 객체λ₯Ό μ°ΎκΈ° μœ„ν•΄ κ³Όλ„ν•˜κ²Œ 점을 찍을 ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.

λ‹€μˆ˜μ˜ 객체λ₯Ό λ‚΄λ³΄λ‚΄λŠ” 경우 λͺ¨λ‘ μ΅œμƒμœ„ λ ˆλ²¨μ— λ°°μΉ˜ν•˜μ„Έμš”. (If you're exporting multiple objects, put them all at top-level)

MyThings.ts

export class SomeType { /* ... */ }
export function someFunc() { /* ... */ }

λ°˜λŒ€λ‘œ κ°€μ Έμ˜¬ λ•Œ:

imported 이름을 λͺ…μ‹œμ μœΌλ‘œ λ‚˜μ—΄ (Explicitly list imported names)

Consumer.ts

import { SomeType, someFunc } from "./MyThings";
let x = new SomeType();
let y = someFunc();

λ‹€μˆ˜λ₯Ό importing ν•˜λŠ” 경우 λ„€μž„μŠ€νŽ˜μ΄μŠ€ import νŒ¨ν„΄ μ‚¬μš© (Use the namespace import pattern if you're importing a large number of things)

MyLargeModule.ts

export class Dog { ... }
export class Cat { ... }
export class Tree { ... }
export class Flower { ... }

Consumer.ts

import * as myLargeModule from "./MyLargeModule.ts";
let x = new myLargeModule.Dog();

ν™•μž₯을 μœ„ν•œ λ‹€μ‹œ 내보내기 (Re-export to extend)

μ’…μ’… λͺ¨λ“ˆμ˜ κΈ°λŠ₯을 ν™•μž₯ν•΄μ•Ό ν•©λ‹ˆλ‹€.
일반적인 JS νŒ¨ν„΄μ€ JQuery ν™•μž₯이 μž‘λ™ν•˜λŠ” 것과 λΉ„μŠ·ν•œ extensions을 μ‚¬μš©ν•˜μ—¬ 원본 객체λ₯Ό λ³΄κ°•ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.
μ•žμ„œ μ–ΈκΈ‰ν–ˆλ“―μ΄ λͺ¨λ“ˆμ€ μ „μ—­ λ„€μž„μŠ€νŽ˜μ΄μŠ€ 객체처럼 λ³‘ν•©λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
ꢌμž₯λ˜λŠ” 해결책은 원본 객체λ₯Ό λ³€ν˜•μ‹œν‚€μ§€ μ•Šκ³  μƒˆλ‘œμš΄ κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ” μƒˆλ‘œμš΄ μ—”ν‹°ν‹°λ₯Ό exportν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

Calculator.ts λͺ¨λ“ˆμ— μ •μ˜λœ κ°„λ‹¨ν•œ 계산기 κ΅¬ν˜„μ„ κ³ λ €ν•΄λ³΄μ„Έμš”.
λ˜ν•œ λͺ¨λ“ˆμ€ μž…λ ₯ λ¬Έμžμ—΄ λͺ©λ‘μ„ μ „λ‹¬ν•˜κ³  끝에 κ²°κ³Όλ₯Ό μž‘μ„±ν•˜μ—¬ 계산기 κΈ°λŠ₯을 ν…ŒμŠ€νŠΈν•˜λŠ” 헬퍼 ν•¨μˆ˜λ₯Ό exports ν•©λ‹ˆλ‹€.

Calculator.ts

export class Calculator {
    private current = 0;
    private memory = 0;
    private operator: string;

    protected processDigit(digit: string, currentValue: number) {
        if (digit >= "0" && digit <= "9") {
            return currentValue * 10 + (digit.charCodeAt(0) - "0".charCodeAt(0));
        }
    }

    protected processOperator(operator: string) {
        if (["+", "-", "*", "/"].indexOf(operator) >= 0) {
            return operator;
        }
    }

    protected evaluateOperator(operator: string, left: number, right: number): number {
        switch (this.operator) {
            case "+": return left + right;
            case "-": return left - right;
            case "*": return left * right;
            case "/": return left / right;
        }
    }

    private evaluate() {
        if (this.operator) {
            this.memory = this.evaluateOperator(this.operator, this.memory, this.current);
        }
        else {
            this.memory = this.current;
        }
        this.current = 0;
    }

    public handelChar(char: string) {
        if (char === "=") {
            this.evaluate();
            return;
        }
        else {
            let value = this.processDigit(char, this.current);
            if (value !== undefined) {
                this.current = value;
                return;
            }
            else {
                let value = this.processOperator(char);
                if (value !== undefined) {
                    this.evaluate();
                    this.operator = value;
                    return;
                }
            }
        }
        throw new Error(`Unsupported input: '${char}'`);
    }

    public getResult() {
        return this.memory;
    }
}

export function test(c: Calculator, input: string) {
    for (let i = 0; i < input.length; i++) {
        c.handelChar(input[i]);
    }

    console.log(`result of '${input}' is '${c.getResult()}'`);
}

λ‹€μŒμ€ test ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œ κ³„μ‚°κΈ°μ˜ κ°„λ‹¨ν•œ ν…ŒμŠ€νŠΈμž…λ‹ˆλ‹€.

TestCalculator.ts

import { Calculator, test } from "./Calculator";


let c = new Calculator();
test(c, "1+2*33/11="); // 9

이제 이것을 ν™•μž₯ν•˜μ—¬ 10이 μ•„λ‹Œ λ‹€λ₯Έ 수의 μž…λ ₯에 λŒ€ν•œ 지원을 μΆ”κ°€ν•˜κΈ° μœ„ν•œ ProgrammerCalculator.tsλ₯Ό μž‘μ„±ν•΄ λ΄…μ‹œλ‹€.

ProgrammerCalculator.ts

import { Calculator } from "./Calculator";

class ProgrammerCalculator extends Calculator {
    static digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];

    constructor(public base: number) {
        super();
        if (base <= 0 || base > ProgrammerCalculator.digits.length) {
            throw new Error("base has to be within 0 to 16 inclusive.");
        }
    }

    protected processDigit(digit: string, currentValue: number) {
        if (ProgrammerCalculator.digits.indexOf(digit) >= 0) {
            return currentValue * this.base + ProgrammerCalculator.digits.indexOf(digit);
        }
    }
}

// μƒˆλ‘­κ²Œ ν™•μž₯된 계산기λ₯Ό κ³„μ‚°κΈ°λ‘œ export ν•©λ‹ˆλ‹€.
export { ProgrammerCalculator as Calculator };

// λ˜ν•œ 헬퍼 ν•¨μˆ˜λ₯Ό export ν•©λ‹ˆλ‹€.
export { test } from "./Calculator";

λ‹€μŒμ€ 우리의 ProgrammerCalculator ν΄λž˜μŠ€μ— λŒ€ν•œ ν…ŒμŠ€νŠΈμž…λ‹ˆλ‹€.
μƒˆλ‘œμš΄ λͺ¨λ“ˆ ProgrammerCalculatorλŠ” μ›λž˜ Calculator λͺ¨λ“ˆκ³Ό λΉ„μŠ·ν•œ API ν˜•νƒœμ„ export ν•˜μ§€λ§Œ 원본 λͺ¨λ“ˆμ˜ μ–΄λ– ν•œ 객체도 λ³΄κ°•ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λ‹€μŒμ€ ProgrammerCalculator ν΄λž˜μŠ€μ— λŒ€ν•œ ν…ŒμŠ€νŠΈμž…λ‹ˆλ‹€:

TestProgrammerCalculator.ts

import { Calculator, test } from "./ProgrammerCalculator";

let c = new Calculator(2);
test(c, "001+010="); // 3

λͺ¨λ“ˆμ—μ„œ λ„€μž„ 슀페이슀λ₯Ό μ‚¬μš©ν•˜μ§€ λ§ˆμ„Έμš” (Do not use namespaces in modules)

λͺ¨λ“ˆ 기반 쑰직으둜 처음 이동할 λ•Œμ˜ νŠΈλ Œλ“œλŠ” μΆ”κ°€ λ„€μž„ 슀페이슀 계측에 exportsλ₯Ό λž˜ν•‘ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.
λͺ¨λ“ˆμ—λŠ” 자체적인 μŠ€μ½”ν”„κ°€ 있으며 exports μ„ μ–Έλ§Œ λͺ¨λ“ˆ μ™ΈλΆ€μ—μ„œ λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.
이λ₯Ό 염두에 두고 λ„€μž„μŠ€νŽ˜μ΄μŠ€λŠ” λͺ¨λ“ˆμ„ μ‚¬μš©ν•  λ•Œ 맀우 μž‘μ€ 값을 μ œκ³΅ν•©λ‹ˆλ‹€.

쑰직 μΈ‘λ©΄μ—μ„œλŠ” λ„€μž„μŠ€νŽ˜μ΄μŠ€κ°€ λ…Όλ¦¬μ μœΌλ‘œ κ΄€λ ¨λœ 객체와 νƒ€μž…μ„ μ „μ—­ μŠ€μ½”ν”„λ‘œ κ·Έλ£Ήν™”ν•  λ•Œ νŽΈλ¦¬ν•©λ‹ˆλ‹€.
예λ₯Ό λ“€μ–΄ C#μ—μ„œλŠ” System.Collections의 λͺ¨λ“  μ»¬λ ‰μ…˜ νƒ€μž…μ„ μ°ΎμŠ΅λ‹ˆλ‹€.

νƒ€μž…μ„ 계측적 λ„€μž„μŠ€νŽ˜μ΄μŠ€λ‘œ κ΅¬μ„±ν•˜μ—¬ μ΄λŸ¬ν•œ νƒ€μž…μ˜ μ‚¬μš©μžμ—κ²Œ ν›Œλ₯­ν•œ "발견" κ²½ν—˜μ„ μ œκ³΅ν•©λ‹ˆλ‹€.
반면 λͺ¨λ“ˆμ€ ν•„μˆ˜μ μœΌλ‘œ 파일 μ‹œμŠ€ν…œμ— 이미 μ‘΄μž¬ν•©λ‹ˆλ‹€.
κ²½λ‘œμ™€ 파일 μ΄λ¦„μœΌλ‘œ ν•΄κ²°ν•΄μ•Ό ν•˜λ―€λ‘œ μ‚¬μš©ν•  μˆ˜μžˆλŠ” 논리적 쑰직 체계가 μžˆμŠ΅λ‹ˆλ‹€.
λͺ©λ‘ λͺ¨λ“ˆμ΄ ν¬ν•¨λœ /collections/generic/ 폴더λ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ „μ—­ μŠ€μ½”ν”„μ—μ„œ 좩돌된 이름을 μ§€μ •ν•˜μ§€ μ•ŠμœΌλ €λ©΄ λ„€μž„μŠ€νŽ˜μ΄μŠ€κ°€ μ€‘μš”ν•©λ‹ˆλ‹€.
예λ₯Ό λ“€μ–΄ My.Application.Customer.AddFormκ³Ό My.Application.Order.AddForm 같은 μ΄λ¦„μ΄μ§€λ§Œ λ‹€λ₯Έ λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό 가진 두 가지 νƒ€μž…μ΄ μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.
κ·ΈλŸ¬λ‚˜ 이것은 λͺ¨λ“ˆκ³Ό κ΄€λ ¨λœ λ¬Έμ œλŠ” μ•„λ‹™λ‹ˆλ‹€.
λͺ¨λ“ˆ λ‚΄μ—μ„œ λ™μΌν•œ 이름을 가진 두 개의 객체λ₯Ό κ°–λŠ” κ·ΈλŸ΄λ“―ν•œ μ΄μœ λŠ” μ—†μŠ΅λ‹ˆλ‹€.
μ‚¬μš©μžλŠ” λͺ¨λ“ˆμ„ μ°Έμ‘°ν•˜λŠ” 데 μ‚¬μš©ν•  이름을 μ„ νƒν•˜κ²Œ λ˜λ―€λ‘œ μš°μ—°ν•œ 이름 μΆ©λŒμ€ λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€.

λͺ¨λ“ˆκ³Ό λ„€μž„μŠ€νŽ˜μ΄μŠ€μ— λŒ€ν•œ μžμ„Έν•œ λ‚΄μš©μ€ [λ„€μž„ μŠ€νŽ˜μ΄μŠ€μ™€ λͺ¨λ“ˆ](./Namespaces and Modules.md)을 μ°Έμ‘°ν•˜μ„Έμš”.

μœ„ν—˜ μ‹ ν˜Έ (Red Flags)

λ‹€μŒμ€ λͺ¨λ‘ λͺ¨λ“ˆ ꡬ쑰화λ₯Ό μœ„ν•œ μœ„ν—˜ μš”μ†Œλ“€μž…λ‹ˆλ‹€.
이 쀑 ν•˜λ‚˜λΌλ„ νŒŒμΌμ— μ μš©λ˜λŠ” 경우 μ™ΈλΆ€ λͺ¨λ“ˆμ˜ λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό μ§€μ •ν•˜λ €κ³  ν•˜μ§€ μ•ŠλŠ”μ§€ λ‹€μ‹œ ν™•μΈν•˜μ„Έμš”.

  • 였직 μ΅œμƒμœ„ 레벨 μ„ μ–Έλ§Œ export namespace Foo { ... }인 파일 (Fooλ₯Ό μ œκ±°ν•˜κ³  λͺ¨λ“  것을 'μœ„λ‘œ' μ΄λ™μ‹œν‚€μ„Έμš”)
  • 단일 export class λ˜λŠ” export functionκ°€ μžˆλŠ” 파일 (export default μ‚¬μš©μ„ κ³ λ €ν•˜μ„Έμš”)
  • μ΅œμƒμœ„ 파일 μœ„μΉ˜μ— λ™μΌν•œ export namespace Foo {λ₯Ό 가진 λ‹€μˆ˜μ˜ 파일 (이것듀이 Foo ν•˜λ‚˜λ‘œ 결합될 것이라고 μƒκ°ν•˜μ§€ λ§ˆμ„Έμš”!)