可选模块加载和其他高级加载场景
在某些情况下,您可能只想在某些条件下加载模块。在 TypeScript 中,我们可以使用下面显示的模式来实现这个和其他高级加载场景,以直接调用模块加载器而不会失去类型安全性。
编译器检测每个模块是否在发出的 JavaScript 中使用。如果模块标识符仅用作类型注释的一部分而从未用作表达式,则不会require
为该模块发出调用。省略未使用的引用是一个很好的性能优化,并且还允许选择性加载这些模块。
该模式的核心思想是该import id = require("...")
语句使我们能够访问模块公开的类型。模块加载器是require
动态调用的(通过),如if
下面的块所示。这利用了引用省略优化,以便仅在需要时加载模块。为了使这种模式起作用,通过 any 定义的符号仅用于类型位置(即永远不会在将被发送到 JavaScript 的位置中)是很重要的。
为了保持类型安全,我们可以使用typeof
关键字。的typeof
关键字,在一个类型的位置使用时,产生一个值的类型,在这种情况下,模块的类型。
1 Node.js 中的动态模块加载 2 declare function require(moduleName: string): any; 3 import { ZipCodeValidator as Zip } from "./ZipCodeValidator"; 4 if (needZipValidation) { 5 let ZipCodeValidator: typeof Zip = require("./ZipCodeValidator"); 6 let validator = new ZipCodeValidator(); 7 if (validator.isAcceptable("...")) { 8 /* ... */ 9 } 10 }
示例:require.js 中的动态模块加载
1 declare function require( 2 moduleNames: string[], 3 onLoad: (...args: any[]) => void 4 ): void; 5 6 import * as Zip from "./ZipCodeValidator"; 7 8 if (needZipValidation) { 9 require(["./ZipCodeValidator"], (ZipCodeValidator: typeof Zip) => { 10 let validator = new ZipCodeValidator.ZipCodeValidator(); 11 if (validator.isAcceptable("...")) { 12 /* ... */ 13 } 14 }); 15 }