模块

从 ECMAScript 2015 开始,JavaScript 有了模块的概念。TypeScript 共享这个概念。

模块在自己的作用域内执行,而不是在全局作用域内执行;这意味着在模块中声明的变量、函数、类等在模块外部是不可见的,除非它们使用 export 表格.x 之一显式导出。相反,要使用从不同模块导出的变量、函数、类、接口等,必须使用 import 表格

模块是声明性的;模块之间的关系是根据文件级别的导入和导出来指定的。

模块使用模块加载器相互导入。在运行时,模块加载器负责在执行模块之前定位和执行模块的所有依赖项。JavaScript 中使用的众所周知的模块加载器是 Node.js 的 CommonJS 模块加载器和 RequireJS 加载器,用于 Web 应用程序中的 AMD 模块。

在 TypeScript 中,就像在 ECMAScript 2015 中一样,任何包含顶级 importexport 的文件都被视为一个模块。相反,没有任何顶级 importexport 声明的文件被视为其内容在全局作用域内可用的脚本(因此也可用于模块)。

导出

导出声明

I1+V/7zgIx0THkZ9lEJ1VJ92aWOCx4r4XC/9T1rNBh4VHtfsYJPu5dx/gpK6FEoUPTqhbve7f1hfNi/li86Khznvt77IOQ1uzIsYoHK19oSNOUPfse8u1mJfUkE2BVzzV5o4Q+I33YzmOfOF1qQeIBaWMoOKDLqoOuuMD+uXxz831TfBiDG7rVx9e0JohXda

StringValidator.ts

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

ZipCodeValidator.ts

import { StringValidator } from "./StringValidator";

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

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

导出语句

lKME2yLSv0vx5KG1KKm5KNsn4nMyjzfJTZ4gvJBqgJ9ywpRR0jU3CPhswbrEwhUCsI/iXil26iV+mRlJXpz+h7Irj8Puj89iLHdS0mH5TqWlDdkiz3dFdx9ZzBrwF3OPBPT4j4DnHaoCxqhdEZ+hgg==

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

重新导出

yQR5ZSypI/LmlmPd/eTqceFmrc5TDctdh8k+6Bo7AKkr9ZAq1NU6J0L08H708KCBJwL4sPzOLcElkYIHrqMs84R75N9mKkbHLBrvZQyEKak0heUynJ8O5Z4ExGOWJtGhdo+lIAGImmPa1+G+LnSxn1ndBGVq8EzyuqIyMSSHhgqTqaJnY2idYPTGI44eao15T4ljKp4YKRn76SX133+ATQ==

ParseIntBasedZipCodeValidator.ts

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

// Export original validator but rename it
export { ZipCodeValidator as RegExpBasedZipCodeValidator } from "./ZipCodeValidator";

Qk0IRyqgSejBHDU94XHDXWQF+J0erbugajsRaliZvkkXIiy8+r7XuTnk3/PSLEYRFa5u5rSj5Wb8ey2yk52pS0BA+FQRP0c30iE/bs959Akg1a65OdeON+8gYdjuHqWkSZLeUmwg1WtOlWp6vPKx/lJkEaIwuxXKinOCnfGe+28t14cv826PD822+M+RgkEk

AllValidators.ts

export * from "./StringValidator"; // exports 'StringValidator' interface
export * from "./ZipCodeValidator"; // exports 'ZipCodeValidator' class and 'numberRegexp' constant value
export * from "./ParseIntBasedZipCodeValidator"; //  exports the 'ParseIntBasedZipCodeValidator' class
// and re-exports 'RegExpBasedZipCodeValidator' as alias
// of the 'ZipCodeValidator' class from 'ZipCodeValidator.ts'
// module.

导入

hudi//nmMwHsM2psbk+kpCOpojveT3J3gQQTCw0epHW8X6hnb9gvai2GlPwnCSSjClFtXABPBFiBXf9dz5dfDsswkf+/KYv8D3L7tHL/kaXa1IZmGix1xIZ+2iyloDWJox2wUwGm1VkdptJFlU9Jgmnut8kmbwocSgrV0fxEe2g=

从模块导入单个导出

import { ZipCodeValidator } from "./ZipCodeValidator";

let myValidator = new ZipCodeValidator();

pqGDNxc2gwFbCv3njFc5HfMq65S9wIkIE8lhxrmdRqg=

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

将整个模块导入单个变量,并使用它来访问模块导出

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

导入仅用于副作用的模块

zPY+RMXQm3OZGI1Ic695xjJuTMdzyhTLIXyut5mo5o6Ch1XehzmmOQTuGBmplMA6R9EOFwBz9a3dMYj5CMNQQ1UXAh3E2rk53CRjym1QCFJU5Gr9bbbjyXOLKX8TRG9PxB0rROGEl7x1CK92ihzVdPdw5H1pG1quZ/nvwm1CPifVPMwQMCFgZBBFjOXRz3czvSeOWyldhr+Q+yvnozpnyQlfjy+iysDCi2t/Lgf/UANV74z2LRiaz00H3NBrPvx5DNGSMHYhUeNs57furMB30DupLJmfVptmylJvOiq7zb50P7fHt3Y0fn+qlgg3LV+E

import "./my-module.js";

导入类型

5xKDHAYFYTHvsmrW40oBKkbqkMEC/9B4aPfs+K245wfTZnWgpI6aRxjbUUOz5FRrkPOPfY0/NYblFFYyj2QMYKO2iLtpW/C+CnRJvELDLvGD6ndjfG0JH2XKD8ihH2DHVT/EQn6e08RuLdkYo7gt6KB4V7szda96m8eUAFoT5tyTBnJShNk+h9b+Zpmc9MwcieioC3QusjXxpAtDoYFp8RZTkFUzpzaqtXGLSpYQ0iSM394g4ClUNJJTOpofEQci8EFWPlpcGqPonMz40kgb3A==

// Re-using the same import
import { APIResponseType } from "./api";

// Explicitly use import type
import type { APIResponseType } from "./api";

// Explicitly pull out a value (getResponse) and a type (APIResponseType) 
import { getResponse, type APIResponseType} from "./api";

o4QwJYXjWSlKBy3mgqo3Ue79y1bIvqiWsTK/PaU9aPRX9V62w1TGltP18ynoVbBAf39YULviLtdXUpwuohxGkkgJCW9SPjmFrqKyYu3IZmT6ww89kE2Muojw4QnwEIXWIreL+vY0CZUce3vEIeRXiCWsK62on3rY6CHjxQ0SCt1UgW0w/QLkJe6OF8UVDmmfj379jG6tt+rdZZkDKIDcBJFysFloizMsBlxKR0YflR5DD7ncfKxGImt6/zd/hXMZNwIjD5o29brxMYbe83Ng3s9MD9cMfVRX+VR9Y52f5qi7fCqJJQqsa5ONk2zS6UWIucYyp7YtRGX8gzxgrSsa/jlBQqLltfEaCO45Cq9x8dzv3V0ApTxoHmjv30tP571NKXm3E56l7xcmt5HohuGRQnUa1u6hUnmNdL2cxc0k/5EErK/Yaz5d1+k4V5RFKjESM/Nn2Lk85kI8fEFjz/fQZ5wL32waj71UPDwsev9kl/EBsXBT9ftZck1CKTG4DmyY

默认导出

68c9NO0as32XO7WKmtc9uO/9GchXm058RRo8vN5smG7YVaU856IxijatVSEK4yH5S2eBbWOufZm+Z9Is0xjHOB9Rsq3Xw+97IL990DDigetVuliQfOgoNQggyN3YKCtIbjfUAI99U8csXL296grfS8vLFG6Fi0qRPUbqMxc1gPYy2g2zYSxWeMKaab6qnO0TrwSsYIAHi7DBhyImd0tOlHn8hdFfs5kMMo9J4FQV2cyMPOE5/+X9yXk51NjetJ6tlMWUPx9t3swV117BAeQwMK9LMEuejjR/mcsndNmUi2KiLSGZlv+PtUbtrFP4B+EjrUDuwt/qOvUWmTR7dC1mFg==

eXj24zkdb9H+c8SsYK+Dfb8OOTzhxiWLUs3UKY9rhvDaxANInEHGz/BuY3ihuNq1qnwpmvYaIkkUb7EMtBaR/3o39WlD8x9Mxzzvm4DiA1C8f0O7A+FOA6/u0X/y11cSha1bnx66PlRVSmtGQt65z7NFSpa32I6S/pRYOlC4al14+MQ80n6cXSSu8ydKgHtnwNsj7I23S7G7Fmizxrv4+T70wfN7vPkulJ4BfQpdAaDMOxEj97A3IP1F7v/6cs4zRKzZ4FRDStIzXreyQooD5rm3eH/QJJQfYo0CRZt5fcw=

JQuery.d.ts

declare let $: JQuery;
export default $;

App.ts

import $ from "jquery";

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

oNyLfesz/BeKx3a5jcMHqtG4b+HrP+5othHzbhk0ZmBmx5N7DPSgcGPmMeU/Vv0KQKFKmlWQZDR6aDw5oQkS1cXVkVn4kuHrADRdwT517Q0bRydFFAHkRqRGbHyY838j0gALIPaYq2wRfZpOLMqduA==

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();

CTbEvplvKkveVBqPX/iXAw==

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

// Use function validate
strings.forEach((s) => {
  console.log(`"${s}" ${validate(s) ? "matches" : "does not match"}`);
});

eXj24zkdb9H+c8SsYK+DfU8v3M2H10EvmUAWBMmfQXhluzlD/EBnZfiETBAxz2Fzw8vD2/MJvd3IEz+poHbIeA==

OneTwoThree.ts

export default "123";

Log.ts

import num from "./OneTwoThree";

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

全部导出为 x

6l2hphvtf3YtEpGsL9DZdUEjk0JyTVzEQlChXziV1P6Oyn1F/X4VRSVYSLgZ+HlTMHYDnyJlrUHMr6j4VxWF28d099AAZfsHkTCr73sKDV625Z3H3eT3hwplPE5EhjEoO1UObPAdQTlenpNfBF6AB/ZG851bI2MqjVLo6lGth756/uXMc8X7657iGUHk9VGT

export * as utilities from "./utilities";

LhMexqznHZKi1eDlN3i+4YZSQxJ0ViOy68vVQmC5R5vaewo8bRFvjwWzt4dp0RFsNUN3KA9ZI8CgGEqbqNBoGCDWON075UAfPsqpkw3WyexkjXd+m5mE8EB4BSzA9Zbs7sgckE6QWNTUMc0D1cfs0Q==

import { utilities } from "./index";

export = 和 import = require()

UZxwaGhWp2tcFyxgaYinjE9Z4pPk+/qtqyLTj8wzkZ0z47jXl5z2EQeBAQa0UA0G5uVwFkZNQh2rgMKQzN9SpyU5FH0GKMKlvF+Q2SXZU4RbKRcfTR2vFEvTjPDZ+H6eN+QcL4hITj480KsLJYA8JaNjctI0MZZ4dMUYYO06LYc=

LNUjvJ3i+UCIq1NNV1EKaW6d4dQkpC+m6pCtRAB0PUASg2Asbnr/rbKVkL220Jzx9j57Xpa3aI12QWZfXT4Ha8T2AC901qIR0pdF4J+fZO4Y5VVhSu8olEXWzGreByp0LO1RvzTthAZPRx483H0MoRVJy8cRvB3HMgem2BqbLczlVP7ODrPQh65O5HLklGVLLcMgD/QP84CmBMMNNrPwSauDxat7BZxw1IwhxcXnBRntLEeIdRSvlqXsMx4fXlpZGTPJIXQEZEkLdnWw+CKgfJWhVwLF5dAtPsKfXDFw63Zxitl2Hzi3a4KgYDgt4fbKqmlxsE6z/E/Tzc9/jyE8Cw==

J1eAA2wY5QPaf16VWabt2G6VZFcZlunGEQ58B3w0n9NTVC1xl8dHP+ZeIEJNmvOMlgi1atWVIujOSpM5FkPP3UFwu1kEXPfRFGvAi8KjsCweTwuJrYG0Z6Pc1wu2z3MI1xAT0WK7sBXuEEJoZ0lcy/ZneXqk/DNAoyycbVLj7bY=

tFk913XYOFc9utWDhdYvbZnGOuO0s+wo2VOCzocc025yRzJO5v7zVlaPigK2H2e9nbol0b8xZ4tew3m6FsXYpJkoPFsdmVBPAXTlxS9WH0d16qudUAo4YtSJQ1glqrMQeYQPLTbxTNTmCjw7I2mHQV+h0uwCdapBljWPaZ2O63zaQTiKj+LfoJWAYPIs/3hOu5wjiGycR0yWAAiLwSD1JQ==

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

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

// Validators to use
let validator = new zip();

// Show whether each string passed each validator
strings.forEach((s) => {
  console.log(
    `"${s}" - ${validator.isAcceptable(s) ? "matches" : "does not match"}`
  );
});

模块代码生成

jD4PSFxfgoxZtaC519gKeVx+ofOaDuAMDTOGh/M3piQhKvLc3XjANSNV9lRlPGplO8xP7Yrqf7+1NKEueCZqyJeYhsdqn+kZQFEsQkx1UWCJSXw2lKffmb38pFsLV8EzoRiz1vrs7ZtDZglAqBR7pxeh235rt4i5ZDBeynv9eveJwERuY693V9Gp3+Ff1xNuEsAG4sei6YJGXo+m+jiBCAtmxlnPeE8o2V2QdDezjpXGdvaNbyvUql0TrX8RqRr5Ej/cw0dMz8hk0TJT+L0/e6WxtykFU3JoZD8vymOSKH1qGqJQ6+CfUGxXIUkyjQRbUb0xbREtxIZxVvIjFgxjQOENImFFUq3EvrLOcJvuzzEqmylo8oEYlK17OfLHgnLn9UouRlqw1B7esc3OcrEw8gNRqFWKhBOgIZQKWA+Lpb0f3jXbl30fVWMokhqlxTIMtcgKdL/eM6llbpRZ6Vy5APFAn35HGSY4XThf1q8wTUr+dJnew0zUJ4o3WRR8yLv9+QBS9Y+9qG/9/IUQVRf2+CRuwYUrKa+Eof9NZfiDmUVa5ZrZnSHNFlGEfSHmPqPgX6SNC0UgNOn65pjsOakBixB18TM3IR9+pIZTlXGJaILaw+STQGiBuQUyygqU7WsUv+cUf200tX1HC1xUCxtZzU5VW/LOxoY4z/Xxzubaqk3SBItiyUZaV04g239iOuucgMbqyWdx3jPFP/rn9zOiLEuyCTUdUCqw2JDz9L9K/Ou3q02uGDnF5dghq9oYlQUPAqv0fLIB8xPIorWL7ZccXzRouo0Y9OKgpufKEkFib00=

5ianz6zj1H+qDAJOD5B2iBDFUWsMPSq105U0tWtz7d43HmpkWAC8IF9MMqvkIlDGjWrz4ZAjaBc/THzBIOno7Dj67jV+XqFWn+INpryxfROH6umoubllZsm11B8ezGW6ctD9v167RriGYtXoKyMuVxLTYPro/dy0GzWwP8+xOV4=

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;
});

系统 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));
    },
  };
});

原生 ECMAScript 2015 模块 SimpleModule.js

import { something } from "./mod";
export var t = something + 1;

简单示例

p5CAr9UsBTuOSVfloR39PR9XSaqbA34L+wC9CJDPw4RGdRDv/6Mz1HmBK5pnoGglQGdjGfKC0WAcMKqTkVdwP1SpqfQfqeEBTcRJB4AMiscQXBM9wdqwLS/88yn5P0Gu8T7j8RoIFKkvJJBIotzeRsOCSbM0IpM66CaPJqzQDVw=

oFzFSZZkjygQ0270ybRWPFbTXqfH9qfrlUFQ+WIF2FHYCyPNuhkZRGM4ZZExBfnCOBmwLDaGkxR4kaAn8QJOf9jCw+SiwKZuUco+hCA7RSqFS/c9y9h3JDQaV8vgMS95foPdFDkE34FscY0Pgp7BOAXtEhY36y6RmUnSItpIvUwYhGqyz1kLlOnrtcJb+ncL+XNszHnOyoapL94SMXXiAxdO7bmrFos2/J9RPS/ujYdKUc7Ychney1CpIWSBrurO

tsc --module commonjs Test.ts

+UYKez6JHyfG0jaJd04jlsnJOHoLGtC5QlgVIp0KUwiiWdym+DeVg6566XvC/dlXnfnX1dpoY2EF9YLP8ry1r7LQMxQFJhTzWj7pGIwz5ReaAlT02gZHUOWF6zfZ4HWlzSfPsOOa6E4UDLTjjsmTUXbZSqaDa6oUgexyspdoLuFUTC9HDF31f2dPo+eSWTHkxBML45SvzWehpptsX/HdqBQfXyCLYBGvGpb32Uqy6Zs=

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

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

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

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

可选模块加载和其他高级加载场景

hH3fwHF5a8ryxTzGDRygkCaVF9zC9obdj3yVs51dnFNU11Bv5MB0FVDoyNR3uCEIVFpdAUAwBNiYy2lp3oxFq+WbgKY6VaIjRLVT06SNW8ZtOAeZQ554PBgBO19oS20poww0JAJtxfYWIr2jcgRcSlVhXukX9xuu4GnJHzUN6bOV3T9ViklkGvMRdV8APycYlgtO1lloNnPu56YIJ2M3Var03EZLdxxflNo8pw5TX4BIAUtvlHoNVykBaZWGK6pVyXz10YiOVZiHdlSHHzKH4TDdqbcCxwRGDoiBgR2twLG/z+faqQyHrX2BFebAt1OC

QkOZUzAZi7n7yZCFRwM4HIoLrJVGsRoEBEq0Kza/qovbJ7kARrzWMlG8q5/oSXBXII+DaxNZZbUJ4EMBzG3nvSc3prrkKiHzT5soBlebmJfkJvGmni1Hoc2Yr3v6dZW6Va0zHOxG9bj+v515ZtYHE31Mkx6cFz7xXsT+oMs3B/ZH7EkOcAbFx1+QaS+k4gosBAU4Yf8VDk8BfpRU6A0Cyg9F1DPqfdJb3dxm+QPO4mwqgfSxBRw1LESsE6kqdkn076NBUUdKTGTsryPPiF7ZoJIjEc35PZm0+PittPpaBeMd7mULzMxNXiegSRgPGcU3wdp54Ty8DBCO2dxzT1+AYobhr2XacKKx2lNavj2cSNKqhQ0CkcbBq1TDgzykLp8/Xqm3URuR2clXQd44jbhh9jTJtGyJJfaybJHbPvgiobc=

yPvRTZcPN49nYJXjwifmmam4NMsudshq2zlYklVP1g4lNB5gYZAonLsSHgnTzlFKKBjUb88YBkw7cGPByBZF2wIFMaB5GkmwfCOF5yQnvU5H4oEtnc/+7VIq8xKMRbwj4fTG8bSJhmP7QITAcmClqDgOWOOd75odbCFijnuTHOYo6fCN08hLABX/wcabeMTGa8qyi7uFVOfPOIBXVD0hyyWthfAe4KqDUkghwgvM8tnBS0uoOlxbj/WkWia4fubZrwHwLtslGg0dPez9FMlfZrZOq51/c16n2+TLDjnBSlyteV6HkClTSECMvO5TaCNbA/zZoAa+GO1YhjJFte9Uir9QNKs3F2bR7+Ts/t6KepWXhQCzbWITkLBrsyIu3NbKKHTxEhb18WMOnCg0vTin3UKUVgFUDABnDnes9iVcod6IgG7wmWIyr8HLsW6LnfRDcQLZ5aUb0u7K5f5BhxVQftq8yTKrkEFvwSXwqVvX4rf5Z0vww+6QBEWfHpaVvRW/Z/tD0CRsCHwYUD4NRqjgLCMwdSyKR9zmqddz+cObfrfEMKB21iCi5UNN+e+t0wxMhKJ/Fxj4XnY7KNXBsBmxzpCg+uZFCv+BfwVDdQDEaxE+Yas+pygaGBPYshmnGr8w

p9TCHFDGRMfWhkfUqvwHOK2MlODLs1GazOpKdJkKDpTahIb2tMCsvPgOw1O6HY68kliDbP8qbJfaCfKlTAcvBCs9IXwwXr3ZmIA5+SwhYmpDVqdmxvKAnTUtANKmgSnk5CkI3qgxCPZZ+pRfuY6qY8qjvPEXyRhqDjcPzjwR8RzKRjz1yRRNSHHLkWfC0LvKuvSw6cYg5HN1AB6lI5cgoqlGIRpMOJmhzeEw/C8ghvWu0qhZSGD3zCXBCljGpp+YwcHPWZrQ9YtaIryx/Zvq3g==

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 中的动态模块加载

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 中的动态模块加载

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 库

pnqjN6rNJequVOWti+capNpW1m6BTEkkoIUL3gnylcvRM/P8j99WGSa5lpE+FX5U6lE6yW76LI3hxAVaJT88e/F3xHsEvP8dNWUsHvCqz5OQknSqgdmPV01j3zrY3Nq6

jGdxNtdyV0woZEX4YoYsfLAyvs6XRALOak/NeQJMgbPmNMtqXa9TmZSQiHUV0AwRhizR+RsjjRRjr/Mqm6ac7ERimx+JaMhDsjDwEx8RzzacUr6wyWZPmwuRh9IMRXoxEp4ah9udKRKTxKK8D2FJM/ZVNJmZioDs8PTPxoAIu5xvERy9r+EyEia3Uqp1YiS+dVpLVksNcBGHYNuMEYTANnZJRrzdRkR6zbfN5ZCmPPhZOmOdHm7n5lJ2YttB3w6DOH5tr741XyXmejGre4hpBPZo7tqi7iLiHpsU39C6N4Y=

环境模块

e93ury4CGs2n5D2yC5cGu2uHfqHLdTp226eH4ysFLiklDtcoNgANTULMaU1jEeHuMxD4mBIJsy99FnZDle/JF7EeoPhrv7fPxQ5rTs7eywnn7BQk1n6KVCz0VX9fEyEqqReWZdSyWTmfBzIyovXdWRqI4wPYCJ8MhV5G2zDeYqVgGBgTM643cVt1GkMB/ZwC6sMnBe6I8kRhmzNwdOPlgCd1mDP2FkbxmSRcw2h7z83tBWoXCx/7nL5/092MKDeJv0OUuihxerscmBN7zXUXABsN61lXCr9Wt06YC9UGab0CIp+scRoPKeeyJah+JTZVEN6f5uy0vjh+GaMs73zr8iM8gy8IhfaebOY2M7YLu8sQ1xf2qaHdaqGH6A5uDCrxBYZuGSUUnwOaXiOBAq92ZlRaogRpW4hmKO0GCPR3mV2/z8jrOnP/bDFqq48THLPPST6XUyIn4Ab/qM3SDqluCL7TXRTonoJRune16cy28rNDaWc+RpnYr977D7cXau2qqIWIX/5FSL8WXFsqILJ8hvJBAjs7kfHusYaa0r3ymPsC8flzL2T7xxJmx1SHQCJSitbV/PR9lD+byNvkc7QoTg==

node.d.ts(简化摘录)

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;
}

AbLqovVHsOhUAqymHsUIcE7i/ag9tB4ujo+2S0ZBD7Hqbttwrc39nO0GoqLa7XbvLakiMHmvQxbWwYzreTyttJspALQUl1xaNpkawduRyVMjCpwIrnZ44e0kwIe7rhDwIt37CvFQptWEzRFfupTlTYLBWipx/Y/QPqbt63f8Yuo6vZ/Qz87Jwrjl8ayTGP09wh42bMh1tAUZ17rVhk6qTrPIxpz0XaeBddWrahxg6PW+7QaK7hCd13F4k9w/TD+U

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

速记环境模块

VcMpe2THfWIPTo6h2EGEEQxeqyVcK5pWIlJt9ioOWljqJC2iyJ5wtBZ9fwmAi5XPsLEwF7mNK+48rJrVFhjGpDoKKD55Mw0mVBRym9LyO+/xbG2Vsl9t7uH1d4/QH7KpE/3dKVLpuwKU2tyLMYheIA==

declarations.d.ts

declare module "hot-new-module";

71yJ+9MyVetTVuB6fDNcquYgz6JG0yyyylUn/EKN+/DS30cMf6QRTnfcSUZ0ohTLoAxguYqZgr/ls4L/U/OyYrBiYk6KqeaqRFGvUxEXKKA=

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

通配符模块声明

Bf9xjBsnRCbov0JPh0HTLM2hTX4EAUgC7NadAa9DEjPpLbEwqjQdWtnrGrtt+6ckCC/R3hXur4bLG98/mUeddABSm6BXkLd5FIeZJl/ytQwTCioawkQogFXSpgjoIOYHJn3RMas7XW4hvMeoFnqR014jBZ8M4p1XZm+x3bV+iRkw+/J+FzYdLbLgw59nLtwLbcCh8EysTiP/l6/fnnqxbxmD7+CMFXa7RMZ5OOukaFWv6fuqOD1KRdPz1F3OUwwE8qWSZvjxLjco+g6E80HX3LuOHZ2K+yHxxTtfdeMiWQvyY+/PUUwGBfBfkXTkA0h3PQg7HdpY6eenx40O9kuNHLTLXo72B++IsyFeP/sUPuI3P2SOF7epDxzB8JdmHXc/MbfVDGqRQBvU8WiIMjdkKA==

declare module "*!text" {
  const content: string;
  export default content;
}
// Some do it the other way around.
declare module "json!*" {
  const value: any;
  export default value;
}

55wbbZYJFSWTl5y+O2hpW3HIIl0/K3qOXKYw7zrtZJZWQQ2nwwv1EGbtN3M2PsvJcK3Hmj0w3n+IBPVeiIai3dHsZYNaogs/jSrAVCSGvXYE2QtrfOaBiPKRvF/dmKji

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

UMD 模块

X0fY2XnrscDyuwSWodhBtzTkFyXbuMXTwyOpzzqZZcFmLLooIilR7CzGryMMnic5C9IE20VGjevOWj2a5Wyd0vd/vECDfc2oG8lGQjBK6n9/szZOaccIJ0XX8o/OYOreNIP3BtwruunA2R7Ddrf76GJJeB08kaStke9GiFVJw6z2YTwiKGSY3TQS3p7buXFIQ9wPpODglv+47GMFNaAO70Yv8Ti/5pCDWFfgK9AaRiaoWSN2WDbBw+zJazeVnP7oAuAQuF2iC5dgj5TFvkxo6zuITlgWQ+arhpXKATgnXcg/8Izh8VDWY2d6rlPlGdTt

math-lib.d.ts

export function isPrime(x: number): boolean;
export as namespace mathLib;

qAUQbOpjjtp6eNMZF1lch95I3nxW07pVboeqZgVkmkCZXVupOd5wD1qDRxETLfYCQg+ziw6bmk0Ate4p07xVbg==

import { isPrime } from "math-lib";
isPrime(2);
mathLib.isPrime(2); // ERROR: can't use the global definition from inside a module

h1JNoemP1CU5gr0uhnV8SOgA6KIECBJNpyaYAmJsyb6rSfcnZd5wh6EhkAu7AQXr6suaOvVy63LNlQKqTUZYCl4Z3hV6hHExj90tj0Jkw01y++FxSSUlgi/sau0IEFARlyLGO+Qzzz6XdUybUdBx9G33j4YaGgaRsj7CJSQHNUM=

mathLib.isPrime(2);

结构化模块指南

尽可能接近顶层导出

6/jJa0CR23VPIB11ec9Eke7sID5KyG/NFsvQgXR342BDb/OkvBgT2hlbC3dC9UdvTuRM3wexfPUVvD6UpRdJydDg4FC5Il0SCcSPcmuF1g33s7xiPLP/JUwyo7n/ZwEXl9R9uROSbgaOR3D+Z4pYdpR6dM8mlfejBDzsESixb/c+N0whnd3mWFM0fACK8v4d3v3UjPf/jXy8K+S9ITsztUCfesG5p+txzxtFj9sfYedBzDZskssCUhqDDw1P7BqN

jqx5wf92lNbhRZT9JIGFpeFztTTSt4min7P5eNBhxsJWZp3XVewK7OqUHW8K5NwRKiKiklbboLshayfGTiMzQplV5ditR3W28uoKG+fbxCNNqM6LltzZA4CYkVzJIgYYq8aUrNB8bQwluafUO2u0F/cD6cNGpXxVTtaVmAg9fafSEz+Lr/0HTAr38a7oY9Rul6XUdkKK+S4Hz+vU6/aKD/LJ68Ymxf6W4fqJvQDuvbTkik75gW3oE2IykOKO7gmVf0+UzxLkg93kVrlTInFPdsQi0UMTIutkvUhDkOSDV0LsOUx/yxil+ebyR/bOb6TX

X56MqgtncLUOv/dP1zXaY6YVlFMLBACZytK30H/g29g/OobfWBFAp4lMtqUVC8mW2oxEvxC37NgvQHt5Zs1buuzUq+cN1bnDIzizQ5Qd2MfX4sfBMWgP4JIllYeFdAcnDr5ak8Zhx5O9Ac1Vd1oFNrZZUTDecKjFx9uw0iNCrQU9PfKP+Z37Lnlwxlv2GCYz1MnS8bLA268lmEBhCgfCdiQwUUi+wyHV/2yYt8bK7WwSFNAZ2nYOO0N26C5WBUYf

如果您只导出单个 class 或 function,请使用 export default

tLxS8u+cDXeqzR+ZitVFIPbsBebCC4QEQYedUG1YCoNJzAfsqnSwrScnPX4n9J7UeKbcnY725RcK/6bFC448cy9lX35kITAE3brRoz2EsGTS7ZtjXHO3Pqm6jbZujCI0MxLPdZ7gwbAdI6TQv+ly92SbBEHtoOuNIqpWbwbUlCGcmk2uoOqfAUyeV6aud0yoRA20A+sU9iPeY34/X8ExRZEoCMdb2Li9zaaSjylA5FAIeA7zg0HZdYP/QeKo+BT/3rEi2LDk1W9f4t80hGocawJVpemUGsodhksixC6OFQgf9UK3adn8j2ULWJjML4zUrD1SUdSo/jQ83yESvCIiTG49tWMDuwG8q6/8SeE3wG/ZCzc/h4dPdesbeFVxeadBv1W6jtO8wkKVMX2ODGz+dA==

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());

g2OYpLUgFBpWRYAbMUJay20BQs6SWy5KNcuGqQkahuQBrqItREGxuv9YwbElX+XQZQMNEEnIPbAmpmAQ/2T4AXHeL0f/MR0i0mUt6FVIVXEzZ7TfKn6UM41PWl0QraTJ+PXeLUjtzJNg+r0U/GSQmmoQSs/TxhaLGSlhZKt/cnAgW6qvpXCbesy5coLT4qXQaLcpmSMGy3Gb0aD4yBMFC+Y7tkuqpNbsv2foEVfYsVk=

如果要导出多个对象,请将它们全部放在顶层

MyThings.ts

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

lVKXG8rtk8foofBaOeLog8jEWoco4zjc5PUhUbLvMgQ=

显式列出导入的名称

Consumer.ts

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

如果要导入大量内容,请使用命名空间导入模式

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();

重新导出以延长

tZ16PkGWEW4Ws0eycJIITr5mLe+JboesyDSA0y9UHUxuqBxt8Sg96bciBJdaBq6U87q//ikjCMCYf+evu29TfvYuPpeXPaRRMb7i1tHdacBqt/DLaF3iNTwfqEoD9+TCKNfnLP9e6D0GgIXjWWJ19whG78P6uI4Z2k5haQE3+6OqavCtDhi9crQ5k8wtXltB4HcUTrqrWBVAV6ayeW1OuANSb1WmkJkTi9HmOBfVorsRUXCUi9xy5ydnFwq+r6zbM8RYOlODCUa6+gxZllRCnR9KVCf4tIFP6LKUFNBEgD9nVyzBA0INzUMy6bxvPtHaA0YF8aPCS9QEyZ6oTCg84ZpvUHSYA6HiL3T4crK3SKMBCLK9V8coHzES/Qr/gOxEaSXFZ367CPLVpxVGYg1SuAznRy97iB36UnqLCCZanW/X8QWNk5AZdjWvvpoQ8zMb

aN1GV37rNszRt7DHAgqvr6QHnMCno5OHoHYycOLgmkyAWAuj0H15H02IacZR90rFnFC+wCU/Q8yPUhuUGYtL9nupIMS8qcQZXas8xIETmUANisY5Iu9v9c8o5Mey0Lc6wIuKjZJH385jdUazdoDoITGKJeZ3JRDwEVpJWyGbUkdeqbLgb8cazpYxHhVqV2jZBCmPwnKnlnNWommJ+nYdezFI8xRCa6S0AaFcM/6oct+CxoeJkEnFY7aMaL1+v3MlR5+VxNfbmHvYjXqH/arEXafZfEY1IE9/Qw+lYc8pYVc=

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 handleChar(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.handleChar(input[i]);
  }

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

zpFYrI0AJldhLWeggItsrRM2KlWXS1fKU/t0L3XVUX4bSpvNv2jAt95IAbQF/xgsNsNjwgTX95DCESHhqayzakTP0IlZ7mCEnzkoPUowz0jge3PMAdSQ3aZbl8PaEtP8

TestCalculator.ts

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

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

MeYGcin7vZnEVX+GQOhmjXFhaOlA1TZqYFOjooTecq1hONGwBX/QLR3GFFYIxd1e7UIB1Y69PU7ar99kwKHbqyfNNDuqWbDyLvCJbc2kDkD1CdTDaF+55cpntZVFxbF1KJ9Ht0T84wSCQmv4bF/pmygorL566e1+epS4Lt2hpKs=

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();
    const maxBase = ProgrammerCalculator.digits.length;
    if (base <= 0 || base > maxBase) {
      throw new Error(`base has to be within 0 to ${maxBase} inclusive.`);
    }
  }

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

// Export the new extended calculator as Calculator
export { ProgrammerCalculator as Calculator };

// Also, export the helper function
export { test } from "./Calculator";

WyTKH/dqG1LAgLdpCQhTrNMBuBuvZYC4lwtFSk4Zsl4U9S1DQ5e3btSBqgAy1bIw9ZN6CpAIipMvEZxoGgWzu/PjADAqJyXVxS05N6EiXVjZ/5ys0pI8e5ty9qz/VRwv/i6Y8yg0x3e88IkFvuUBeZ3n4H/Ues8Vyot327K+JxLUj6PSiShOPyR1YyYiYBMMU2x9BOZLEySgfMJ5OXum+9DYMGvm4RRs6dah/kH0C4NmW7PpXdPNf08ttFv+D93Foe0T+YajzZMF2HATFjd0gf/+kaCoGd8A1WhsiF9qQJo=

TestProgrammerCalculator.ts

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

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

不要在模块中使用命名空间

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

Red Flags

7zakGtJFcpq/1G8ch7dwYSDsr9hYg+70qyoCfhFsiK3/JypZeQoE3k8YIvPidK/zuDoVlqlkxVAk6tIupvkoXVi+l3Q+H735arV/rrmkg1ar1H7ZEPSxBr6DVAqYi3WsSx58iWhbPSZLdvPSYLjdQnxlw02QetzVNbC4vgMAMMSaPIBxymSqx/DMtLnCTxNmcBYL2C2wGs35NnwEYGFTcQ==

    iuKG4hBrKmmtJoY2vW6DBTRtvIlsGg3yYQ7isNwhNaj5ODvS+Htobk66lQsG1aOIMhPbNqcS+yOQ/qqfBZiKe4rHiuwHS5bvrcwfqhjIhbIDkhZTc+6RA+7WiBdpMy9/VT+rvy+L/K+AfCtGk0+IxrcIsOsvMA2bqe//mWWy0vquCh31XlXbA7OWGtEAu6/YKcM46Q+h0CAyS8ljGofKLGWwbTQIBRhT6jO2LL41ctklMxtV+jMb15qLUDaNjzs/ZCLYx9U+tRKq6vafUeYhDFjNJHW/3LSePyikndhiH8sXf5g/gseW4M4ffzigqeNR9/CMOZMmdNeHFwC3guz6mk0nuL+MUtdSZxeFpCCcZd6ekcg24IisAjHWO++oIlHyHEbqRnM4nyAqTX0uQ+R0Rc0Fydui8Hp+MbVYwyOKV88=