正如您所提到的,正是缺乏环境声明引发了这个问题。
我们可以将所有的导入过程总结如下。
导入语句实际上做的事情:
- 导入我们要导入的模块的“规范”,即导入模块的“合约”。该合约可以从我们自己编写的 ts 代码中找到,也可以从可以通过例如 tds 提供的声明文件 (d.ts) 中找到。编译器使用此规范来确保代码的类型正确,并由工具使用来提供智能感知。
- 在应用程序运行时导入实际代码,然后在应用程序运行期间启用模块的增量下载
此外,可以通过两种方式访问模块:
- 以相对的方式,即导入另一个模块的代码的位置,例如 import {Dummy} from './dummy'
- 以绝对方式,即从应用程序根目录。掺杂这个,编译器会扫描所有子目录以找到正确的指定模块,然后尝试加载它
当我们尝试访问应用程序本身中描述的模块时,我们通常使用第一个选项,即我们编写的 ts 代码 当我们从诸如 react、jquery、bootstrap 等供应商模块导入代码时,我们通常使用第二个选项。我们通常使用 tsd 工具导入已经生成的模块描述,这些声明文件会自动放入“typing”子目录中。并行我们需要下载实际代码以使应用程序运行;我们可以通过使用 jspm 工具来执行此操作(例如,如果我们使用“系统”编译选项),该工具会将 js 文件下载到 jspm_packages 子目录中。
例如,如果我们通过 jspm 下载了一个还没有 d.ts 声明文件的 js 模块,我们将不得不定义一个。我建议把它也放在 tsd 最初生成的“typings”子目录中。
声明文件可以有多种定义方式,但我们可以通过以下两种方式进行简化:
- 在给定文件中使用“export”语句,例如 //file dummy.d.ts export class Dummy { name : string }
并通过以下方式导入文件:
import {Dummy} from 'dummy'
并通过以下方式将其导入另一个文件:
import {Dummy} fom 'mydummy'
如果这两种方法看起来非常相似,第二种方法可以在单独的文件中声明相同的“mydummy”模块,编译器会自动合并所有声明。我们可能会注意到,在第二种方法中,模块的名称不是文件的名称,就像在第一种方法中一样。