夜猫子的知识栈 夜猫子的知识栈
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

夜猫子

前端练习生
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • TypeScript基础

  • TypeScript进阶

    • 声明合并
    • declare声明
    • TS的(.d.ts)文件
    • 命名空间namespace
      • 命名空间:namespace
      • namespace 官方示例
      • 多命名空间文件
      • 别名
      • 环境命名空间(declare)
    • 理解TS模块
  • TS 从零实现 axios

  • 《TypeScript》
  • TypeScript进阶
夜猫子
2023-03-07
目录

命名空间namespace

# 命名空间

# 命名空间:namespace

命名空间一般用来定义对象(需结合declare)。使用命名空间的好处是,可以自定义对外可见/不可见的的类型或值。极大的规避了全局命名冲突的问题。同时我们可以使用 export 来对外暴露命名空间内的值或类型。

在代码量较大的情况下,为了避免命名空间冲突,可以将相似的函数、类、接口防止在命名空间内。

命名空间可以将代码包裹起来,只对外暴露需要在外部访问的对象,命名空间内通过 export 向外导出。

命名空间是内部模块,主要用于组织代码,避免命名冲突。

# namespace 官方示例

namespace Validation {
  // 通过export暴露的类型/值,可在namespaace外部访问
  // 暴露一个interface,其包含一个方法签名
  export interface StringValidator {
    isAcceptable(s: string): boolean;
  }
  // 没有使用export来导出,只能在namespace内部访问
  const lettersRegexp = /^[A-Za-z]+$/;
  const numberRegexp = /^[0-9]+$/;
  // 暴露两个class
  export class LettersOnlyValidator implements StringValidator {
    isAcceptable(s: string) {
      return lettersRegexp.test(s);
    }
  }
  export class ZipCodeValidator implements StringValidator {
    isAcceptable(s: string) {
      return s.length === 5 && numberRegexp.test(s);
    }
  }
}
// 测试用例
let strings = ["Hello", "98052", "101"];
// 字符串索引签名,初始化变量
let validators: { [s: string]: Validation.StringValidator } = {};
// 添加两个属性,分别是一个validator实例
validators["ZIP code"] = new Validation.ZipCodeValidator();
validators["Letters only"] = new Validation.LettersOnlyValidator();
    
// 开始测试
for (let s of strings) {
  for (let name in validators) {
    console.log(
      `"${s}" - ${
        validators[name].isAcceptable(s) ? "matches" : "does not match"
      } ${name}`
    );
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

可以发现,我们可以在 namespace 中自由定义类型或者值,只要不导出,它就是私有的。

# 多命名空间文件

namespace 的声明是可以合并的,那么这就使得多文件命名空间成为了可能。但一个项目变得很大时,namespace 也会变得很大,将所有内容都写在一个 namespace 文件中就会变得不太明智。因此 TS 支持我们将 namespace 进行模块化,将内容拆分到多个文件中。

模块化:通过三斜杠指令:/// <reference path="xxx" />来指定路径,告诉编译器文件之间的依赖关系,注意 三斜杠指令应位于文件的开头。

(其实三斜杠指令不仅可以运用在命名空间,环境声明:declare 等同样可以)

以上面的官方示例为例进行拆分:

1.主体

Validation.js:

namespace Validation{
  export interface StringValidator {
    isAcceptable(s: string): boolean;
  }
}
1
2
3
4
5

2.扩展字母校验器

LettersOnlyValidator.js:

// 首先通过三斜杠指令来引入需要合并的命名空间
/// <reference path="Validation.ts" />
namespace Validation{
    // 私有成员,仅在当前namaspace中可见
    const lettersRegexp = /^[A-Za-z]+$/;
    // 导出共享成员
	export class LettersOnlyValidator implements StringValidator {
    	isAcceptable(s: string) {
      		return lettersRegexp.test(s);
    	}
  	}
}
1
2
3
4
5
6
7
8
9
10
11
12

3.继续扩展

ZipCodeValidator.js:

/// <reference path="Validation.ts" />
namespace Validation{
    // 私有成员,仅在当前namaspace中可见
    const numberRegexp = /^[0-9]+$/;
    // 导出共享成员
	export class ZipCodeValidator implements StringValidator {
    	isAcceptable(s: string) {
      		return s.length === 5 && numberRegexp.test(s);
    	}
  	}
}
1
2
3
4
5
6
7
8
9
10
11

4.使用

笔记

合并命名空间后,如果想要在其他文件中使用对应的命名空间模块,仍然需要使用三斜杆指令来引入相关的 namespace 文件。

test.ts:

// 使用三斜杠指令来引入相关的namespace文件
/// <reference path="Validation.ts" />
/// <reference path="LettersOnlyValidator.ts" />
/// <reference path="ZipCodeValidator.ts" />

// 以下用法和在最开始没有拆分使相同
// 测试用例
let strings = ["Hello", "98052", "101"];
// 变量声明,索引签名
let validators: { [s: string]: Validation.StringValidator } = {};
// 添加validator实例
validators["ZIP code"] = new Validation.ZipCodeValidator();
validators["Letters only"] = new Validation.LettersOnlyValidator();

// 开始测试
for (let s of strings) {
  for (let name in validators) {
    console.log(
      `"${s}" - ${
        validators[name].isAcceptable(s) ? "matches" : "does not match"
      } ${name}`
    );
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 别名

可以通过给命名空间设置别名的方式来简化引用。

// 官方示例的第一个嵌套namespace
namespace Shapes {
  const age = 18
  export const getAge = () => age
  export namespace Polygons {
    export class Triangle {}
    export class Square {}
  }
}
// 可以给一般成员起别名
import age = Shapes.getAge
// 也可以给嵌套的namespace起别名
import polygons = Shapes.Polygons;
let sq = new polygons.Square(); // 和 'new Shapes.Polygons.Square()' 一样
1
2
3
4
5
6
7
8
9
10
11
12
13
14

注意

注意,这不要和模块的导入语法import q = require(X)相混淆,这俩不是同一个东西。命名空间的import newName = X.y.x只是单纯地给命名空间的成员起一个别名而已。

# 环境命名空间(declare)

其中涉及一个名词:ambient,我们通常将那些还没有定义的声明叫做 ambient,这些声明往往出现在 .d.ts 的拓展文件中,因为有些库并不是使用 TS 写的,而是使用 JS 写的,而大多数JS库所暴露的都是一个顶级的object,为了让这些库中暴露的 API 能够支持 TS,我们可以用环境命名空间来定义这些第三方库的形状。

// 注意 '环境' 的声明都需要添加declare关键字
// 以D3库为例,声明没有定义实现的接口
declare namespace D3 {
  export interface Selectors {
    select: {
      (selector: string): Selection;
      (element: EventTarget): Selection;
    };
  }
  export interface Event {
    x: number;
    y: number;
  }
  export interface Base extends Selectors {
    event: Event;
  }
}
// 声明没有分配的值
declare var d3: D3.Base;
/* d3的形状是
{	
	select: {
      (selector: string): Selection;
      (element: EventTarget): Selection;
    };
    event: Event;
}
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
编辑 (opens new window)
上次更新: 2023/8/22 19:22:36
TS的(.d.ts)文件
理解TS模块

← TS的(.d.ts)文件 理解TS模块→

最近更新
01
IoC 解决了什么痛点问题?
03-10
02
如何调试 Nest 项目
03-10
03
Provider注入对象
03-10
更多文章>
Copyright © 2019-2025 Study | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式