Skip to content

Latest commit

Β 

History

History
269 lines (207 loc) Β· 10.1 KB

Namespaces.md

File metadata and controls

269 lines (207 loc) Β· 10.1 KB

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

μ†Œκ°œ

이 κ²Œμ‹œλ¬Όμ€ TypeScript의 λ„€μž„μŠ€νŽ˜μ΄μŠ€(μ΄μ „μ˜ "λ‚΄λΆ€ λͺ¨λ“ˆ")λ₯Ό μ‚¬μš©ν•˜μ—¬ μ½”λ“œλ₯Ό κ΅¬μ„±ν•˜λŠ” λ‹€μ–‘ν•œ 방법을 κ°„λž΅ν•˜κ²Œ μ„€λͺ…ν•©λ‹ˆλ‹€.
μš©μ–΄μ— λŒ€ν•΄ μ–ΈκΈ‰ν•  λ•Œ "λ‚΄λΆ€(internal) λͺ¨λ“ˆ"은 이제 "λ„€μž„μŠ€νŽ˜μ΄μŠ€"둜 μ–ΈκΈ‰λ©λ‹ˆλ‹€.
또 λ‚΄λΆ€ λͺ¨λ“ˆμ„ μ„ μ–Έν•  λ•Œ module ν‚€μ›Œλ“œκ°€ μ‚¬μš©λœ 곳이라면 μ–΄λ””μ—μ„œλ‚˜ namespace ν‚€μ›Œλ“œλ₯Ό λŒ€μ‹  μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
λΉ„μŠ·ν•œ μ΄λ¦„μ˜ μš©μ–΄λ‘œ μ˜€λ²„λ‘œλ“œν•¨μœΌλ‘œμ¨ μƒˆλ‘œμš΄ μ‚¬μš©μžμ—κ²Œ μ£ΌλŠ” ν˜Όλ™μ„ λ°©μ§€ν•©λ‹ˆλ‹€.

첫 걸음 (First steps)

λ¨Όμ € 이 νŽ˜μ΄μ§€μ˜ 예제둜 μ‚¬μš©ν•  ν”„λ‘œκ·Έλž¨μ—μ„œλΆ€ν„° μ‹œμž‘ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.
μ›Ή νŽ˜μ΄μ§€μ˜ 양식에 λŒ€ν•œ μ‚¬μš©μž μž…λ ₯을 ν™•μΈν•˜κ±°λ‚˜ μ™ΈλΆ€μ—μ„œ μ œκ³΅ν•˜λŠ” 데이터 파일의 ν˜•μ‹μ„ ν™•μΈν•˜κΈ° μœ„ν•΄ μž‘μ„±ν•  수 μžˆλŠ” κ°„λ‹¨ν•œ λ¬Έμžμ—΄ μœ νš¨μ„± 검사기λ₯Ό μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

단일 파일의 μœ νš¨μ„± 검사기 (Validators in a single file)

interface StringValidator {
    isAcceptable(s: string): boolean;
}

let lettersRegexp = /^[A-Za-z]+$/;
let numberRegexp = /^[0-9]+$/;

class LettersOnlyValidator implements StringValidator {
    isAcceptable(s: string) {
        return lettersRegexp.test(s);
    }
}

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

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

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

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

Namespacing

Validatorλ₯Ό 더 좔가함에 따라 νƒ€μž…μ„ μΆ”μ ν•˜κ³  λ‹€λ₯Έ κ°μ²΄μ™€μ˜ 이름 μΆ©λŒμ— λŒ€ν•΄ κ±±μ •ν•˜μ§€ μ•Šμ„ 수 μžˆλŠ” μΌμ’…μ˜ 쑰직 체계λ₯Ό 원할 κ²ƒμž…λ‹ˆλ‹€.
μ „μ—­ λ„€μž„μŠ€νŽ˜μ΄μŠ€μ— λ‹€λ₯Έ 이름을 많이 μΆ”κ°€ν•˜λŠ” λŒ€μ‹  객체λ₯Ό λ„€μž„μŠ€νŽ˜μ΄μŠ€λ‘œ λ§ˆλ¬΄λ¦¬ν•©μ‹œλ‹€.

이 μ˜ˆμ œμ—μ„œλŠ” λͺ¨λ“  validator κ΄€λ ¨ μ—”ν‹°ν‹°λ₯Ό ValidationλΌλŠ” λ„€μž„μŠ€νŽ˜μ΄μŠ€λ‘œ μ΄λ™ν•©λ‹ˆλ‹€.
μ—¬κΈ°μ„œ μΈν„°νŽ˜μ΄μŠ€μ™€ 클래슀λ₯Ό λ„€μž„μŠ€νŽ˜μ΄μŠ€ μ™ΈλΆ€μ—μ„œ λ³Ό 수 있기λ₯Ό μ›ν•˜κΈ° λ•Œλ¬Έμ— exportλ₯Ό 머리말에 λΆ™μž…λ‹ˆλ‹€.
λ°˜λŒ€λ‘œ λ³€μˆ˜ lettersRegexp와 numberRegexpλŠ” κ΅¬ν˜„ μ„ΈλΆ€ μ‚¬ν•­μ΄λ―€λ‘œ λ…ΈμΆœλ˜μ§€ μ•Šμ€ μƒνƒœλ‘œ λ‚¨μ•„μžˆμ–΄ λ„€μž„μŠ€νŽ˜μ΄μŠ€ μ™ΈλΆ€μ˜ μ½”λ“œμ—λŠ” 보이지 μ•ŠμŠ΅λ‹ˆλ‹€.
파일의 μ•„λž˜μͺ½μ— μžˆλŠ” ν…ŒμŠ€νŠΈ μ½”λ“œμ—μ„œ (예: Validation.LettersOnlyValidator)와 같이 λ„€μž„μŠ€νŽ˜μ΄μŠ€ μ™ΈλΆ€μ—μ„œ μ‚¬μš©ν•  경우 νƒ€μž…μ˜ 이름을 확인해야 ν•©λ‹ˆλ‹€.

Namespaced Validators

namespace Validation {
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }

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

    export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {
            return lettersRegexp.test(s);
        }
    }

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

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

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

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

파일 λΆ„ν•  (Splitting Across Files)

μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ 증가함에 따라 μ½”λ“œλ₯Ό μ—¬λŸ¬ 파일둜 λ‚˜λˆ„μ–΄ μœ μ§€ λ³΄μˆ˜ν•˜κΈ° μ‰½κ²Œ λ§Œλ“€λ €κ³  ν•©λ‹ˆλ‹€.

Multi-file namespaces

μ—¬κΈ°μ„œ Validation λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό λ§Žμ€ νŒŒμΌλ“€λ‘œ λ‚˜λˆŒ κ²ƒμž…λ‹ˆλ‹€.
νŒŒμΌμ€ λ³„κ°œμ΄μ§€λ§Œ 각각 λ™μΌν•œ λ„€μž„μŠ€νŽ˜μ΄μŠ€μ— κΈ°μ—¬ν•  수 있으며 λͺ¨λ“  파일이 ν•œκ³³μ—μ„œ μ •μ˜λœ κ²ƒμ²˜λŸΌ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
파일 κ°„ μ˜μ‘΄μ„±μ΄ 있기 λ•Œλ¬Έμ— μ»΄νŒŒμΌλŸ¬μ—κ²Œ νŒŒμΌλ“€ κ°„μ˜ 관계λ₯Ό μ•Œλ €μ£ΌλŠ” μ°Έμ‘° νƒœκ·Έλ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€.
ν…ŒμŠ€νŠΈ μ½”λ“œλŠ” λ³€κ²½λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

Validation.ts
namespace Validation {
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }
}
LettersOnlyValidator.ts
/// <reference path="Validation.ts" />
namespace Validation {
    const lettersRegexp = /^[A-Za-z]+$/;
    export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {
            return lettersRegexp.test(s);
        }
    }
}
ZipCodeValidator.ts
/// <reference path="Validation.ts" />
namespace Validation {
    const numberRegexp = /^[0-9]+$/;
    export class ZipCodeValidator implements StringValidator {
        isAcceptable(s: string) {
            return s.length === 5 && numberRegexp.test(s);
        }
    }
}
Test.ts
/// <reference path="Validation.ts" />
/// <reference path="LettersOnlyValidator.ts" />
/// <reference path="ZipCodeValidator.ts" />

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

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

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

μ—¬λŸ¬ 파일이 ν¬ν•¨λ˜λ©΄ 컴파일된 λͺ¨λ“  μ½”λ“œλ₯Ό λ‘œλ“œν•΄μ•Ό ν•©λ‹ˆλ‹€.
이 μž‘μ—…μ—λŠ” 두 가지 방법이 μžˆμŠ΅λ‹ˆλ‹€.

λ¨Όμ € --outFile을 μ‚¬μš©ν•˜μ—¬ λͺ¨λ“  μž…λ ₯ νŒŒμΌμ„ 단일 JavaScript 좜λ ₯ 파일둜 컴파일 ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

tsc --outFile sample.js Test.ts

μ»΄νŒŒμΌλŸ¬λŠ” νŒŒμΌμ— μžˆλŠ” μ°Έμ‘° νƒœκ·Έλ₯Ό 기반으둜 좜λ ₯ νŒŒμΌμ„ μžλ™μœΌλ‘œ μ •λ ¬ν•©λ‹ˆλ‹€.
각 νŒŒμΌμ„ κ°œλ³„μ μœΌλ‘œ 지정할 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€:

tsc --outFile sample.js Validation.ts LettersOnlyValidator.ts ZipCodeValidator.ts Test.ts

λ˜λŠ” νŒŒμΌλ³„ 컴파일(κΈ°λ³Έκ°’)을 μ‚¬μš©ν•˜μ—¬ 각 μž…λ ₯ νŒŒμΌμ— λŒ€ν•œ JavaScript νŒŒμΌμ„ ν•˜λ‚˜μ”© λ°©μΆœν•  수 μžˆμŠ΅λ‹ˆλ‹€.
λ§Œμ•½ μ—¬λŸ¬ 개의 JS 파일이 μƒμ„±λ˜λ©΄ μ›Ή νŽ˜μ΄μ§€μ— μžˆλŠ” <script>νƒœκ·Έλ₯Ό μ‚¬μš©ν•˜μ—¬ 방좜된 각 νŒŒμΌμ„ μ μ ˆν•œ μˆœμ„œλŒ€λ‘œ λ‘œλ“œν•΄μ•Ό ν•©λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄:

MyTestPage.html (excerpt)
    <script src="Validation.js" type="text/javascript" />
    <script src="LettersOnlyValidator.js" type="text/javascript" />
    <script src="ZipCodeValidator.js" type="text/javascript" />
    <script src="Test.js" type="text/javascript" />

별칭 (Aliases)

λ„€μž„μŠ€νŽ˜μ΄μŠ€ μž‘μ—…μ„ λ‹¨μˆœν™”ν•  수 μžˆλŠ” 또 λ‹€λ₯Έ 방법은 import x = require("name")λ₯Ό μ‚¬μš©ν•˜μ—¬ 일반적으둜 μ‚¬μš©λ˜λŠ” 객체의 더 짧은 이름을 μƒμ„±ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.
μ΄λŸ¬ν•œ μ’…λ₯˜μ˜ imports(λ³„μΉ­μœΌλ‘œ 뢈림)λ₯Ό λͺ¨λ“ˆ importsμ—μ„œ μƒμ„±λœ 객체λ₯Ό ν¬ν•¨ν•œ λͺ¨λ“  μ’…λ₯˜μ˜ μ‹λ³„μžμ— μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

namespace Shapes {
    export namespace Polygons {
        export class Triangle { }
        export class Square { }
    }
}

import polygons = Shapes.Polygons;
let sq = new polygons.Square(); // 'new Shapes.Polygons.Square()'와 λ™μΌν•©λ‹ˆλ‹€

require ν‚€μ›Œλ“œλŠ” μ‚¬μš©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λŒ€μ‹  κ°€μ Έμ˜€λŠ” 심볼에 κ±Έλ§žμ€ 이름을 직접 ν• λ‹Ήν•©λ‹ˆλ‹€.
이것은 var μ‚¬μš©κ³Ό λΉ„μŠ·ν•˜μ§€λ§Œ κ°€μ Έμ˜¨ μ‹¬λ³Όμ˜ νƒ€μž…κ³Ό λ„€μž„μŠ€νŽ˜μ΄μŠ€ μ˜λ―Έμ— λŒ€ν•΄μ„œλ„ μž‘μš©ν•©λ‹ˆλ‹€.
μ€‘μš”ν•œ 점은, κ°’μ˜ 경우 importλŠ” μ›λž˜ 심볼과 λ³„κ°œμ˜ μ°Έμ‘°μ΄λ―€λ‘œ μ•¨λ¦¬μ–΄μ‹±λœ var에 λŒ€ν•œ λ³€κ²½ 사항은 μ›λž˜ λ³€μˆ˜μ— λ°˜μ˜λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λ‹€λ₯Έ JavaScript 라이브러리둜 μž‘μ—…ν•˜κΈ° (Working with Other JavaScript Libraries)

TypeScriptμ—μ„œ μž‘μ„±λ˜μ§€ μ•Šμ€ 라이브러리의 ν˜•νƒœμ„ μ„€λͺ…ν•˜λ €λ©΄ λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ ν‘œμ‹œν•˜λŠ” APIλ₯Ό μ„ μ–Έν•΄μ•Ό ν•©λ‹ˆλ‹€.
λŒ€λΆ€λΆ„μ˜ JavaScript λΌμ΄λΈŒλŸ¬λ¦¬λŠ” λͺ‡ 개의 μ΅œμƒμœ„ 레벨의 객체만 λ…ΈμΆœν•˜λ―€λ‘œ λ„€μž„μŠ€νŽ˜μ΄μŠ€λŠ” 객체λ₯Ό ν‘œν˜„ν•  μˆ˜μžˆλŠ” 쒋은 λ°©λ²•μž…λ‹ˆλ‹€.

κ΅¬ν˜„μ„ "ambient"으둜 μ •μ˜ν•˜μ§€ μ•ŠλŠ” 선언을 ν˜ΈμΆœν•©λ‹ˆλ‹€.
일반적으둜 이듀은 .d.ts νŒŒμΌμ— μ •μ˜λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.
C/C++에 μ΅μˆ™ν•˜λ‹€λ©΄ .d.ts 파일둜 생각할 수 μžˆμŠ΅λ‹ˆλ‹€.
λͺ‡ 가지 예λ₯Ό μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

Ambient Namespaces

인기 μžˆλŠ” 라이브러리 D3λŠ” d3μ΄λΌλŠ” μ „μ—­ κ°μ²΄μ—μ„œ κΈ°λŠ₯을 μ •μ˜ν•©λ‹ˆλ‹€.
이 λΌμ΄λΈŒλŸ¬λ¦¬λŠ” <script> νƒœκ·Έ (λͺ¨λ“ˆ λ‘œλ” λŒ€μ‹ )λ₯Ό 톡해 λ‘œλ“œλ˜κΈ° λ•Œλ¬Έμ— 선언에 λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜μ—¬ κ·Έ ν˜•νƒœμ„ μ •μ˜ν•©λ‹ˆλ‹€.
TypeScript μ»΄νŒŒμΌλŸ¬κ°€ 이 ν˜•νƒœμ„ 보렀면 ambient λ„€μž„μŠ€νŽ˜μ΄μŠ€ 선언을 μ‚¬μš©ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ λ‹€μŒκ³Ό 같이 μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

D3.d.ts (simplified excerpt)
declare namespace D3 {
    export interface Selectors {
        select: {
            (selector: string): Selection;
            (element: EventTarget): Selection;
        };
    }

    export interface Event {
        x: number;
        y: number;
    }

    export interface Base extends Selectors {
        event: Event;
    }
}

declare var d3: D3.Base;