공부공부/TS

[typescript 핸드북] 11. 네임스페이스

고생쨩 2024. 2. 19. 09:34
728x90

typescript 핸드북 학습내용 정리
https://typescript-kr.github.io/pages/the-handbook.html

네임스페이스

첫번째 단계

단일 파일 검사기

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"];

// 사용할 검사기
let validators: { [s: string]: StringValidator; } = {};
validators["ZIP code"] = new ZipCodeValidator();
validators["Letters only"] = new LettersOnlyValidator();

// 각 문자열이 각 검사기를 통과했는지 표시
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 }'.`);
    }
}

네임스페이스 적용하기

네임스페이스화된 검사기

// 모든 검사기를 ```Validation```이라는 네임스페이스로 묶음
namespace Validation {
    // export 된 애들은 외부에서 접근 가능
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }

    // 아래 정규식 2개는 구현 세부 사항이므로 네임스페이스 외부 코드에서 접근할 수 없음
    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"];

// 사용할 검사기
let validators: { [s: string]: Validation.StringValidator; } = {};
validators["ZIP code"] = new Validation.ZipCodeValidator();
validators["Letters only"] = new Validation.LettersOnlyValidator();

// 각 문자열이 각 검사기를 통과했는지 표시
for (let s of strings) {
    for (let name in validators) {
        console.log(`"${ s }" - ${ validators[name].isAcceptable(s) ? "matches" : "does not match" } ${ name }`);
    }
}

파일 간 분할

앱 규모가 커지면 코드를 여러 파일로 분할하셈

다중 파일 네임스페이스

  • 하나의 네임스페이스를 여러 파일로 분할
  • 파일이 분리되어있어도 같은 네임스페이스에 기여하고, 한곳에서 정의된것처럼 사용가능
  • 파일 간 의존성이 존재하므로, 참조 태그를 추가하여 컴파일러에게 파일간의 관계를 알릴 것
/**
 * Validation.ts
 */
namespace Validation{
    export interface StringValidator{
        isAcceptable(s: string): boolean;
    }
}

/**
 * LettersOnlyValidators.ts
 */
/// <reference path="Validation.ts" />
namespace Validation {
    const lettersRegexp = /^[A-Za-z]+$/;
    export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {
            return lettersRegexp.test(s);
        }
    }
}
/**
 * ZipCodeValidators.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" />

// Some samples to try
let strings = ["Hello", "98052", "101"];

// Validators to use
let validators: { [s: string]: Validation.StringValidator; } = {};
validators["ZIP code"] = new Validation.ZipCodeValidator();
validators["Letters only"] = new Validation.LettersOnlyValidator();

// Show whether each string passed each validator
for (let s of strings) {
    for (let name in validators) {
        console.log(`"${ s }" - ${ validators[name].isAcceptable(s) ? "matches" : "does not match" } ${ name }`);
    }
}

파일이 여러개 있을때 컴파일된 코드가 모두 로드되는지 확인하는 방법

  1. –outFile 플래그를 사용하여 연결출력을 사용할 수 있음
tsc --outFile sample.js Text.ts
  1. 파일을 개별적으로 지정
tsc --outFile sample.js Validation.ts LettersOnlyValidator.ts ZipCodeValidator.ts Test.ts
  1. 각각 파일을 js로 생성하고 웹페이지에서 script 태그로 다 불러와 쓰기
<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)

  • 네임스페이스를 단순화하는 방법으로는 대입이 있음 ex) import q = x.y.z
  • import x = require ("name") 같은 구문과 혼동하지 않기 위해 특정심볼에 별칭을 생성함. 이런 종류의 가져오기는 모듈 가져오기에서 생성된 객체를 포함하여 모든 종류의 식별자에 대해 사용할 수 있음
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 키워드르 사용하지 않음. 정해진 이름으로 직접 할당함.
원래 심벌과 별개의 참조이므로 변경내용은 원래 변수에 반영되지 않음

다른 JS 라이브러리로 작업하기

  • 대부분의 JS 라이브러리는 소수의 최상위 객체만 노출하므로 네임스페이스를 사용하는 것이 좋음
  • 구현을 정의하지 않은 선언을 ambient 라고 부름. 일반적으로 .d.ts 에 정의되어있음. -> 구현을 정의하지 않았다. = 쓰는데 필요한 것만 아세요.

Ambient 네임스페이스

  • D3를 예로 들고 있음.
// D3.d.ts 간단 버전
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;

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.