「译」TypeScript终极指南二:模块的导入导出

原文来自 The Definitive TypeScript Guide -(https://www.sitepen.com/blog/2018/10/29/update-the-definitive-typescript-guide/

使用let和const

ES2015引入了使用let和const这两种声明变量的新方法。使用let或const声明变量几乎总是优于使用var,因为与其他语言相比,var声明具有一些不寻常的作用域规则。与使用var声明的变量不同,使用let声明的变量是“块作用域”变量,这些变量在它们的包含块或循环之外是不可见的。这有助于避免使用重复的变量名引起的意外冲突。使用const声明变量的作用域与使用let的声明类似 - 最大的区别在于,如果你尝试重新赋予const变量值,则编译时会报错。但是,你仍然可以更改由const声明的对象中的某个属性。尽可能使用const有助于程序员发出关于这些变量将会如何表现的意图 - 这使得代码更容易理解。

TypeScript 2.0添加了readonly关键字,该关键字不允许重新赋值,并且具有non-writable(不可写)属性或仅有get访问器的属性。这并不意味着non-primitives(非原生类型)是不可变的。

import 和 export

为了开始讨论如何编写TypeScript,我们首先需要了解如何创建和加载TypeScript文件。 TypeScript文件使用.ts文件扩展名,与AMD和CommonJS一样,每个TypeScript文件名义上代表单独的一个模块。 在TypeScript中导入模块遵循ES模块(ESM)API:

默认情况下,相对路径的模块解析在TypeScript中与在AMD和CommonJS中相同,是相对于引用模块的当前文件目录进行解析。 绝对路径的模块解析方式则略有不同。首先,如果存在匹配的环境模块声明(ambient module declaration,在本系列的之后文章中会有介绍到),它的值会被用作as - is。 否则,编译器从包含引用模块的当前文件目录开始遍历文件系统,在每个父目录中查找.ts文件,然后是.d.ts文件,直到找到匹配项为止。

在TypeScript 2.0之前,支持两种解析模块名称的方法:classic(模块名称始终解析为文件,模块使用文件夹遍历搜索)和node(使用类似于Node.js的模块加载机制)。 遗憾的是,这两种方法都没有解决相对于baseUrl定义模块的方法,这是AMD系统(如Dojo、RequireJS以及SystemJS等)使用的方法,尽管仍在 named/mapped base URLs标准提案中努力。

TypeScript团队没有为TypeScript 2.0引入第三方模块解析,而是在现有系统中添加了配置选项来解决这个问题:baseUrl、paths和rootDirs。只有在设置了baseUrl时才能使用paths。 如果至少定义了其中的一个属性,那么TypeScript编译器将会尝试使用它来解析模块名,如果失败了,将会回到原来默认的步骤。

可以使用export关键字从模块导出值:

使用星号(*)导入整个模块将会使模块的导出物在本地具有相同的名称:foo、bar和MyClass。 要从其他模块使用上述代码中导出的这些值,只需导入模块并访问其导出的属性:

要导入单个属性,请使用花括号括起属性名称:

你可以通过在export后添加default关键字来指定默认导出:

这相当于从一个AMD工厂函数返回一个值,或者为CommonJS中的module.exports赋一个值。 要使用该值,你只需直接import并使用它:

提供没有花括号的导入标识符将加载默认导入,并且它将隐式地命名为你指定的任何内容。 可以使用as关键字对其他导入进行命名:

要将模块的导出物附加到一个命名属性上,就像你将属性赋值给AMD或CommonJS的exports对象时一样,为星型(*)的导入提供命名即可:

请注意,当用TypeScript的classes(2.2+)来使用mixins时,有一些微妙的细节将在本系列后期中关于classes的主题部分中进行描述。

未完待续,敬请期待下一篇