# 模块与命名空间

# 模块

也和ES6的模块类似

一个一个导出

// a.js
export function save():void {
  console.log('导出成功')
}

export function get():void {
  console.log('get导入成功')
}

export var name:string = 'chang'

// 导入
import {save, get, name } from './a';
save();
get();

统一导出

// b.js
function update():void {
  console.log('导出成功')
}

function deletes():void {
  console.log('导出成功')
}

var age:string = 'chang'

// 导入
export { update, deletes as delete, age } from './b';

save();
delete();

默认导出

// c.js
function deletes():void {
  console.log('导出成功')
}
export default deletes;

// 导入
import deletes from './c';
deletes();

# 命名空间

为避免这种变量命名相冲突,可将相似功能的函数、类、接口等放在命名空间内,使用 namespace 定义,里面的值使用 export 导出,使用时就像一个对象一样。

命名空间和模块的区别: 命名空间为内部模块,主要用于组织代码,避免命名冲突,模块ts的外部模块简称,侧重代码的复用, 一个模块里可能有多个命名空间。

多个命名空间

namespace A {
  export let a = 'xxx'
  export interface Options {
    name: string
    age: number
  }
}
namespace B {
  export let b = 5
  export let c = 'ccc'
}

// 重名会自动合并
namespace B {
  export let d = 123
}
console.log(A.a)
console.log(B.b)
console.log(B.d) // 123

嵌套使用

namespace A {
  export namespace B {
    export const c = 5
  }
}

console.log(A.B.c)

抽离命名空间

把命名空间抽离到单独的文件中,然后通过模块引入,也可以直接使用

// 模块文件animal.js,一个模块内可以放多个命名空间

// 命名空间A
namespace A {
  interface Animal {
    name: string
    eat(food: string):void
  }

  // 需要通过export 暴露
  export class Dog implements Animal {
    name:string
    constructor(name: string) {
      this.name = name
    }
    eat(food:string):void {
      console.log(`${this.name}eat ${food}`)
    }
  }

  export class Cat implements Animal {
    name:string
    constructor(name: string) {
      this.name = name
    }
    eat(food:string):void {
      console.log(`${this.name}eat ${food}`)
    }
  }
}
// 命名空间B
namespace B {
  interface Animal {
    name: string
    eat(food: string):void
  }

  // 需要通过export 暴露
  export class Dog implements Animal {
    name:string
    constructor(name: string) {
      this.name = name
    }
    eat(food:string):void {
      console.log(`${this.name}eat ${food}`)
    }
  }

  export class Cat implements Animal {
    name:string
    constructor(name: string) {
      this.name = name
    }
    eat(food:string):void {
      console.log(`${this.name}eat ${food}`)
    }
  }
}

export {A, B}

引入模块中的命名空间

import {A, B} from './modules/animal'

var dog = new A.Dog('狗')
dog.eat('狗粮')
var cat = new B.Cat('小花')
cat.eat('猫粮')

# 三斜线指令

三斜线指令也是文件导入,通过 /// <reference path="..." /> 方式,path跟路径,引入文件,和import差不多。三斜线指令只能放在文件的最上面,它的上面只能有注释或者其他三斜线指令。

import {A, B} from './modules/animal'

// 三斜线写法
/// <reference path="./modules/animal.ts" />