全局模块

在默认情况下,在TypeScript 文件中写下的代码,它是处于全局命名空间中:

  1. // 定义的变量、类型等在全局命名空间中
  2. const foo = 123;
  3. type name = string;
  1. // 可以不用导入而直接引用
  2. const bar = foo; // allowed
  3. let xjp: name; // allowed

使用全局变量空间是危险的,因为它会与文件内的代码命名冲突。推荐使用文件模块。
所以一般会见到有的文件模块会导出空的对象:

  1. let name: string = 'xjp' // 如果外面也有其它地方声明了name变量就会报错
  2. export {} // 作用,表明这是一个单独的文件模块,里面声明的变量不会共享影响到全局

文件模块

文件模块也被称为外部模块。如果TypeScript 文件里含有 import 或者 export,那么它会在这个文件中创建一个本地的作用域:

  1. // 在全局命名空间里,不再有 foo
  2. export const foo = 123;
  1. // const bar = foo; // ERROR: "cannot find name 'foo'"
  2. // 不能再直接使用,而需要导入再使用
  3. import { foo } from './foo';
  4. const bar = foo; // allow

动态导入表达式

动态导入表达式是 ECMAScript 的一个新功能,它允许你在程序的任意位置异步加载一个模块。
webpack 实现代码分割的方式有两种:使用 import() (首选,ECMAScript 的提案)和 require.ensure() (最后考虑,webpack 具体实现)。

  1. // 懒加载 moment 库,同时也希望使用代码分割的功能,这意味 moment 会被分割到一个单独的 JavaScript文件,当它被使用时,会被异步加载
  2. import(/* webpackChunkName: "momentjs" */ 'moment')
  3. .then(moment => {
  4. // 懒加载的模块拥有所有的类型,并且能够按期工作
  5. // 类型检查会工作,代码引用也会工作 :100:
  6. const time = moment().format();
  7. console.log('TypeScript >= 2.4.0 Dynamic Import Expression:');
  8. console.log(time);
  9. })
  10. .catch(err => {
  11. console.log('Failed to load moment', err);
  12. });

重要的提示

  • 使用 “module”: “esnext” 选项:TypeScript 会保留 import() 语句,该语句用于 Webpack Code Splitting。

.d.ts

修改原始类型

在 TypeScript 中,接口是开放式的,这意味着当你想使用不存在的成员时,推荐创建一个称为 global.d.ts 的特殊文件,TypeScript 将会自动接收它。修改添加至 Window,Math,Date,String 的一些例子:

  1. // helloWorld自动添加至全局 Window 接口
  2. interface Window {
  3. helloWorld(): void;
  4. }
  5. interface Math {
  6. seedrandom(seed?: string): void;
  7. }
  8. // Date的声明是:declare var Date: DateConstructor;
  9. interface DateConstructor {
  10. today(): Date
  11. }
  12. // endsWith自动添加至全局 String 接口
  13. interface String {
  14. endsWith(suffix: string): boolean;
  15. }
  16. String.prototype.endsWith = function(suffix: string): boolean {
  17. const str: string = this;
  18. return str && str.indexOf(suffix, str.length - suffix.length) !== -1;
  19. };
  20. // 使用:
  21. window.helloWorld = () => console.log('hello world');
  22. Math.seedrandom('Any string you want');
  23. const today = Date.today();
  24. console.log('foo bas'.endsWith('bas')); // true

declare

  • declare声明的是全局的类型,默认不需要再导出(除非是declare module)可以直接使用;
  • declare里不可以再重复declare(除非是declare global) ```typescript declare type Nullable = T | null; declare type Recordable = Record;

// 这样TS就可以识别vue文件 declare module ‘*.vue’ { import { DefineComponent } from ‘vue’ const Component: DefineComponent<{}, {}, any> export default Component // 必须要导出 } ```