36
loading...
This website collects cookies to deliver better user experience
이 포스트는 TypeScript - Modules를 번역 및 학습한 내용입니다.
import
키워드를 통해 불러올 수 있다. 이를 가능하게 하는 것은 모듈 로더이다. 모듈 로더는 런타임에 import된 모듈(디펜던시)의 위치를 확인한다. 자바스크립트에서 사용되는 모듈 로더의 종류는 크게 두 가지이다.import
, 혹은 export
키워드를 포함한 파일은 모듈로 처리된다. 그 외(import
, export
키워드가 없는 파일)는 일반 스크립트(글로벌 스코프를 공유하는)로 처리된다.export
키워드를 사용하면, 선언된 모든 식별자(변수, 함수, 클래스, 타입, 인터페이스 등)를 export 할 수 있다.// StringValidator.ts
export interface StringValidator {
isAcceptable(s: string): boolean;
}
// ZipCodeValidator.ts
import { StringValidator } from './StringValidator';
export const numberRegex = /^[0-9]+$/;
export class ZipCodeValidator implements StringValidator {
isAcceptable(s: string) {
return s.length === 5 && numberRegex.test(s);
}
}
// ZipCodeValidator.ts
import { StringValidator } from './StringValidator';
export const numberRegex = /^[0-9]+$/;
class ZipCodeValidator implements StringValidator {
isAcceptable(s: string) {
return s.legnth === 5 && numberRegex.test(s);
}
}
// mainValidator로 이름 변경 후 export
export { ZipCodeValidator as mainValidator };
ParseIntBasedZipCodeValidator.ts
에서 ZipCodeValidator.ts
에 작성된 ZipCodeValidator
클래스를 re-export 할 수 있다. 이때 ZipCodeValidator
를 import하지 않는다는 것에 주의해야한다.// ParseIntBasedZipCodeValidator.ts
export class ParseIntBasedZipCodeValidator {
isAcceptable(s: string) {
return s.length === 5 && parseInt(s).toString() === s;
}
}
// ZipCodeValidator를 rename하여 re-export
export { ZipCodeValidator as RegExpBasedZipCodeValidator } from "./ZipCodeValidator";
export * from 'module'
문법을 사용한다.// AllValidators.ts
// StringValidator 인터페이스 export
export * from './StringValidator';
// ZipCodeValidator 클래스, numberRegexp 변수 export
export * from './ZipCodeValidator';
// ParseIntBasedZipCodeValidator 클래스 export
// RegExpBasedZipCodeValidator 클래스 export (ZipCodeValidator.ts의 ZipCodeValidator 클래스를 rename하여 re-export)
export * from "./ParseIntBasedZipCodeValidator";
export * as namespace
문법을 사용하여 export 대상을 네임스페이스로 랩핑하여 re-export 할 수 있다. 이를 적용하여 위 예제를 일부 수정하면 아래와 같다.// AllValidators.ts
// ZipCodeValidator 클래스, numberRegexp 변수를 validator 네임스페이스로 래핑하여 export
export * as validator from './ZipCodeValidator';
import
키워드를 사용하여 export된 모듈을 로드 할 수 있다.import { ZipCodeValidator } from "./ZipCodeValidator";
const myValidator = new ZipCodeValidator();
// ZipCodeValidator를 ZCV로 rename
import { ZipCodeValidator as ZCV } from "./ZipCodeValidator";
const myValidator = new ZCV();
import * as validator from './ZipCodeValidator';
const myVlidator = new validator.ZipCodeValidator();
import './my-module.js';
import type
문법을 사용했다. 하지만 3.8버전부터 import
키워드로 type을 import 할 수 있다.// import 키워드 사용
import { APIResponseType } from "./api";
// import type 사용
import type { APIResponseType } from "./api";
import type
문은 컴파일 시 제거된다는 것이 보장된다.default
키워드를 사용하며, 하나의 모듈에서 한 번만 사용 가능하다. default export된 모듈을 import 할 때는 이전에 사용했던 문법과 다른 문법을 사용한다.// JQuery.d.ts
declare let $: JQuery;
export default $;
// App.ts
import $ from 'jquery';
// 꼭 같은 이름으로 import 할 필요는 없다. 원하는 이름으로 import 할 수 있다.
// import jquery from 'jquery';
$("button.continue").html("Next Step...");
default
키워드를 바로 사용 할 수 있다. 이때 클래스 혹은 함수 이름 작성을 생략할 수 있다.// ZipCodeValidator.ts
// with name
export default class ZipCodeValidator {
static numberRegexp = /^[0-9]+$/;
isAcceptable(s: string) {
return s.length === 5 && ZipCodeValidator.numberRegexp.test(s);
}
}
// ZipCodeValidator.ts
// without name
export default class {
static numberRegexp = /^[0-9]+$/;
isAcceptable(s: string) {
return s.length === 5 && ZipCodeValidator.numberRegexp.test(s);
}
}
// Tests.ts
import validator from "./ZipCodeValidator";
let myValidator = new validator();
// OneTwoThree.ts
export default '123';
// Log.ts
import num from "./OneTwoThree";
console.log(num); // "123"
export =
문법을 지원한다. export =
문법 사용 시 하나의 객체만을 export 할 수 있다. 이때 export 대상은 클래스, 인터페이스, 네임스페이스, 함수, 혹은 열거형(Enum)이 될 수 있다.export =
문법을 사용하여 export된 모듈을 import 할 때 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 validator = new zip();
SimpleModule
모듈을 컴파일한 결과이다.// SimpleModule.ts
import m = require("mod");
export let t = m.something + 1;
// SimpleModule.js
define(["require", "exports", "./mod"], function (require, exports, mod_1) {
exports.t = mod_1.something + 1;
});
// SimpleModule.js
var mod_1 = require("./mod");
exports.t = mod_1.something + 1;
// 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;
});
// 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));
},
};
});
// SimpleModule.js
import { something } from "./mod";
export var t = something + 1;
require
호출문은 emit된 자바스크립트 파일에 포함되지 않는다.import id = require("...")
문을 사용하면 해당 모듈의 타입에 접근 할 수 있다. 아래 코드는 Node.js에서 Dynamic 모듈 로딩을 구현한 예제이다.declare function require(moduleName: string): any;
// 1. Zip은 타입 표기로만 사용된다. 즉, emit된 JS 파일에 require("./ZipCodeValidator")문이 포함되지 않는다.
import { ZipCodeValidator as Zip } from './ZipCodeValidator';
if (needZipValidation) {
// 2. ZipCodeValidator가 필요한 경우, require문으로 import한다.
let ZipCodeValidator: typeof Zip = require("./ZipCodeValidator");
}
.d.ts
파일에 작성되어 있다.// node.d.ts
declare module "url" {
export interface Url {
protocol?: string;
hostname?: string;
pathname?: string;
}
export function parse(
urlStr: string,
parseQueryString?: string,
slashesDenoteHost?: string
): Url;
}
declare module "path" {
export function normalize(p: string): string;
export function join(...paths: any[]): string;
export var sep: string;
}
node.d.ts
파일을 /// <reference>
로 추가하면된다./// <reference path="node.d.ts"/>
import * as URL from 'url';
let myUrl = URL.parse("http://www.typescriptlang.org");
declare module "url";
import { parse } from 'url';
parse("...");
// 주의: shorthand declaration으로 작성된 모듈은 any type이다.
// math-lib.d.ts
export function isPrime(x: number): boolean;
export as namespace mathLib;
import { isPrime } from "math-lib";
isPrime(2);
mathLib.isPrime(2); // ERROR: can't use the global definition from inside a module
mathLib.isPrime(2);
export default
문법을 사용한다. default export된 모듈을 import 할 때 원하는 이름으로 rename 할 수 있고, 불필요한 .
체이닝을 줄일 수 있다.export * as namespace
X)import * as namespace
X). 단, import 하는 모듈이 너무 많을 경우 namespace import를 사용한다.Calculator
클래스를 확장한 ProgrammerCalculator
클래스를 export할 때 아래와 같이 작성 할 수 있다.// Calculator.ts
export class Calculator {
private current = 0;
private memory = 0;
private operator: string;
protected processDigit(digit: string, currentValue: number) {
// ...
}
protected processOperator(operator: string) {
// ...
}
protected evaluateOperator(
operator: string,
left: number,
right: number
): number {
// ...
}
private evaluate() {
// ...
}
public handleChar(char: string) {
// ...
}
public getResult() {
// ...
}
}
export function test(c: Calculator, input: string) {
// ...
}
// ProgrammerCalculator.ts
import { Calculator } from "./Calculator";
class ProgrammerCalculator extends Calculator {
static digits = [ /* ... */ ];
constructor(public base: number) {
super();
// ...
}
protected processDigit(digit: string, currentValue: number) {
// ...
}
}
// 기존 Calculator를 변경하지 않고 확장하여 export
export { ProgrammerCalculator as Calculator };
// 기존 test를 re-export
export { test } from "./Calculator";
export namespace Foo {...}
)은 해당 namespace를 제거한 후 하위에 선언된 모든 것을 1레벨 올린다.export namespace Foo {...}
는 하나의 Foo
로 병합되지 않는다.