TS 中的模块与命名空间以及声明文件(不完整)

3,400 阅读5分钟

声明文件 declare

声明一个全局库模板,将声明 declare 建议声明在单独的文件内部,声明文件一般是以 .d.ts 为后缀名,还需要注意的是,声明文件的内部是不能包含代码实现的。

declare 基本使用

1. 声明一个全局变量 var let const 
declare let str: string
declare let arr: (number | string)[] = []
declare let obj: { [key: string]: any} = {}

2. 声明一个全局函数
declare function getName(str: string):void

3. 声明类
declare class D {
  private name: string;
  constructor(name: string)
  public getName():void
}

4. 声明接口
declare interface A {
    name: string;
    num: number;
    str?:string
}

声明文件的引入

当我们写好一个声明文件,我们可以通过 三斜线指令 将定义好的声明文件引入到 TS 文件,进行使用

/// <reference path="./1.d.ts" />

声明好的内容如何进行使用

声明外部模块 declare module

declare module 'url' {
    let name: string;
    export interface A {
        num: number;
        str: string;
    }
}

定义好的外部模块通过 import module = require('module')的方式进行引入

import url = require('url')
function sum(option:url.A):void {
    console.log(option.num)
}

为什么module的后面跟的是 引号,官网中可以看到,就是为了更方便的引入,并且在之前的TS 版本,写法也是有一些变化。

声明外部命名空间 declare namesplace

外部命名空间,也就是所说的(我的理解)外部模块的另一种写法,在官网模块与命名空间部分,开始都有提到,之前的版本与现在的版本写法有些不同

1. 之前的版本写法
derlare module url {}

2. 现在被更改为
derlare namesplace url {}

外部的命名空间通过使用 /// 三斜线指令进行引入使用

/// <reference path="./1.d.ts" />

模块

export | import

使用 export 导出任何的声明 (例如: 变量、方法、函数、对象、类等等),都可以使用 export 进行导出,并且一个文件的内部是可以存在多个 export 的。

1.ts

export class User {
  private name: string;
  constructor(name: string) {
    this.name = name
  }
  public getName():void {
    console.log(this.name);
  }
}

使用 import 关键字将 1.ts 中的导出的类,导入到2.ts 中进行使用

import {User} from './1'
let n = new User('小明')
console.log(n.getName());

as 重命名

在导出某一个方法或者是类的时候,由于导出的名字过长,我们可以使用 as 的关键词,对导出的方法进行重命名,在使用 import 导入方法的时候,也可以使用 as 进行重命名的操作

注意在模块中的 as 要与 TS 中的断言 as 要区分开,他们的功能不同,所以在使用的时候注意一下,不要搞混他们的概念,由于是使用的是一个关键词,可能会导致混淆

1. ts 
export function user(name: string):string {
    console.log(name)
}
2.ts
import {user as u} from '/1'

u('小明')

* 全部导出

在文件的内部,无需使用 export 对方法、对象、类、接口进行一一导出,如果这个文件内部所有的内容,在我这个文件的内部都需要使用,我就可以到导入模块的时候,使用 * 将其全部导入,进行使用

import * as vs from '/1'

在本模块的内部,我就可以通过 vs 打点的方式,调用 1.ts 中定义的所有内容

default 默认导出

在一个模块文件的内部,只允许 default 出现一次,也就是说一个模块文件的内部只能使用一次 default,多次使用是无效的。

1. ts
class User {
  public name: string;
  constructor(name: string) {
    this.name = name
  }
  public getName(str: string): void {
    console.log(str);
  }
}
export default {
  User
}
import vs from './1'
console.log(vs);

export= 和 import module = require()

具体的介绍官网还是比较标准的,只是在这里说一下 export = 可以将模块内部的内容进行导出,导出可以是类、接口、命名空间、函数或枚举。

1.TS
let str: string = '测试'
class User {
  private name: string;
  constructor(name: string) {
    this.name = name
  }
  getName(): void {
    console.log(this.name);
  }
}
export = {
  str,
  User
}

2.TS
import vs = require('./1')

命名空间

单文件命名空间

命名空间,使用他明确的目的就是去解决命名冲突的问题,一个标识符可以在多了命名空间里面进行使用,不会发生冲突,他们的各自含义以及作用都是不同的。

在 TypeScript 通过使用关键字 namespace 创建一个命名空间

namespace Validation {
    
}

在命名空间的内部,定义类、函数、对象、变量、接口、泛型等等,如果外部想要使用 命名空间内部定义的内容,命名空间的内部就需要使用 export 关键字,将外面要用到的内容进行导出,如果有一些内容不想外部访问到,可以不适用export 直接像正常书写 TS 一样即可

namespace Validation {
    export class User {
        public str: string;
        constructor(name: string) {
            this.str = name
        }
    }
}

使用
let user =new Validation.User('测试')
user.getName()

在调用的时候,通过命名空间的名字,打点去调用内部导出的类、接口等等。

多文件命名空间

多文件命名空间,也就是将一个命名空间里的内容,存放在多个文件的内部,由于他们之间具有依赖的关系,就需要使用 引用标签 告诉编译器,他们之间的关系

使用时需要注意的是,命名空间之间的关系

引用标签的使用方式

/// <reference path="Validation.ts" />

在编译的时候,需要注意的点就是,确保所有涉及到的文件都要被编译的指令加载到,所以第一种方式就是,所有涉及到的文件同时编译,使用--outFile 对多个文件进行编译

tsc --outFile sum.js 3.ts

tsc --outFile 打包后输出的文件 引用多个命名空间的文件

/// 指令

指令用于告诉编译器,某一个文件在被编译的时候,需要依赖的文件,一起将依赖的文件进行编译

指令被分成两个,一个是path,另一个是type,另外三个仅作为了解

path=

使用path,一般多用于声明文件的引入,声明文件与声明文件至今存在着依赖的关系,在编译时候,需要将所有的涉及到的,到要进行依赖

/// <reference path = "" />

type=

这个指令是用来声明 依赖的; 一个 /// <reference types="..." />指令则声明了对某个包的依赖。

/// <reference types="node" />

总结

  1. 声明文件的引入方式
/// <reference path = " runoob.d.ts" />
  1. 声明模块的引入方式(外部)
import module = require('module')
  1. 命名空间的引入方式(外部)
/// <reference path = " namesplace.d.ts" />