Young Kbt blog Young Kbt blog
首页
  • java基础

    • Java基础
    • Java集合
    • Java反射
    • JavaJUC
    • JavaJVM
  • Java容器

    • JavaWeb
  • Java版本新特性

    • Java新特性
  • SQL 数据库

    • MySQL
    • Oracle
  • NoSQL 数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • ActiveMQ
    • RabbitMQ
    • RocketMQ
    • Kafka
  • 进阶服务

    • Nginx
  • Spring
  • Spring Boot
  • Spring Security
  • 设计模式
  • 算法
  • 知识
  • 管理

    • Maven
    • Git
  • 部署

    • Linux
    • Docker
    • Jenkins
    • Kubernetes
  • 进阶

    • TypeScript
  • 框架

    • React
    • Vue2
    • Vue3
  • 轮子工具
  • 项目工程
  • 友情链接
  • 本站

    • 分类
    • 标签
    • 归档
  • 我的

    • 收藏
    • 关于
    • Vue2-Admin (opens new window)
    • Vue3-Admin(完善) (opens new window)
GitHub (opens new window)

Shp Liu

朝圣的使徒,正在走向编程的至高殿堂!
首页
  • java基础

    • Java基础
    • Java集合
    • Java反射
    • JavaJUC
    • JavaJVM
  • Java容器

    • JavaWeb
  • Java版本新特性

    • Java新特性
  • SQL 数据库

    • MySQL
    • Oracle
  • NoSQL 数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • ActiveMQ
    • RabbitMQ
    • RocketMQ
    • Kafka
  • 进阶服务

    • Nginx
  • Spring
  • Spring Boot
  • Spring Security
  • 设计模式
  • 算法
  • 知识
  • 管理

    • Maven
    • Git
  • 部署

    • Linux
    • Docker
    • Jenkins
    • Kubernetes
  • 进阶

    • TypeScript
  • 框架

    • React
    • Vue2
    • Vue3
  • 轮子工具
  • 项目工程
  • 友情链接
  • 本站

    • 分类
    • 标签
    • 归档
  • 我的

    • 收藏
    • 关于
    • Vue2-Admin (opens new window)
    • Vue3-Admin(完善) (opens new window)
GitHub (opens new window)
  • 超文本标记语言 - Html

  • 解释编程语言 - JavaScript

  • JS 超集语言 - TypeScript

    • TypeScript - 介绍
    • TypeScript - 安装和使用
    • TypeScript - 基本类型
    • TypeScript - 编译和配置
    • TypeScript - 文件打包
    • TypeScript - 接口
    • TypeScript - 函数
    • TypeScript - 类
    • TypeScript - 泛型
    • TypeScript - 类型推断
    • TypeScript - 高级类型
    • TypeScript Office - 入门
    • TypeScript Office - 常用类型
    • TypeScript Office - 类型缩小
    • TypeScript Office - 更多函数
    • TypeScript Office - 对象类型
    • TypeScript Office - 类型操纵
    • TypeScript Office - 类
    • TypeScript Office - 模块
    • TypeScript Office - 变量声明
    • TypeScript Office - 类型推断
    • TypeScript Office - 枚举
    • TypeScript Office - 公共类型
    • TypeScript Office - Symbols
    • TypeScript Office - 类型兼容性
    • TypeScript Office - 迭代器和生成器
    • TypeScript Office - 装饰器
    • TypeScript Office - JSX
    • TypeScript Office - 混入
    • TypeScript Office - 三斜线指令
    • TypeScript Office - 模块进阶
    • TypeScript Office - 模块解析
    • TypeScript Office - 命名空间
      • 命名空间
      • 第一步
      • 单一文件中的验证器
      • 命名方式
      • 命名的验证器
      • 跨文件分割
      • 多文件命名空间
      • 别名
      • 与其他JavaScript库一起工作
    • TypeScript Office - 命名空间与模块
    • TypeScript Office - 声明合并
  • 界面构建框架 - React

  • 渐进式框架 - Vue2

  • 渐进式框架 - Vue3

  • 前端
  • JS 超集语言 - TypeScript
Young Kbt
2022-09-16
目录

TypeScript Office - 命名空间

  • 命名空间
  • 第一步
  • 单一文件中的验证器
  • 命名方式
  • 命名的验证器
  • 跨文件分割
  • 多文件命名空间
  • 别名
  • 与其他JavaScript库一起工作

# 命名空间

关于术语的说明:需要注意的是,在 TypeScript 1.5 中,术语已经改变。「内部模块」现在是「命名空间」。「外部模块」现在只是「模块」,以便与 ECMAScript 2015 的术语保持一致,(即 module X { 等同于现在的 namespace X { )。

这篇文章概述了在 TypeScript 中使用命名空间(以前的「内部模块」),用各种方法来组织你的代码。正如我们在术语说明中所暗示的,「内部模块」现在被称为「命名空间」。此外,在声明内部模块时,凡是使用 module 关键字的地方,都可以而且应该使用 namespace 关键字来代替。这就避免了新用户因使用类似的术语而感到困惑。

# 第一步

让我们从本页中我们将使用的程序开始。作为例子,我们写了一小套简单的字符串验证器,用来检查用户在网页中的表单中的输入,或者检查外部提供的数据文件的格式。

# 单一文件中的验证器

interface StringValidator {
    isAcceptable(s: string): boolean;
}
let lettersRegexp = /^[A-Za-z]+$/;
let numberRegexp = /^[0-9]+$/;
class LettersOnlyValidator implements StringValidator {
    isAcceptable(s: string) {
        return lettersRegexp.test(s);
    }
}
class ZipCodeValidator implements StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}
// 一些测试案例
let strings = ["Hello", "98052", "101"];
// 要使用的验证器
let validators: { [s: string]: StringValidator } = {};
validators["ZIP code"] = new ZipCodeValidator();
validators["Letters only"] = new LettersOnlyValidator();
// 显示每一个字符串是否通过了每个验证器
for (let s of strings) {
    for (let name in validators) {
        let isMatch = validators[name].isAcceptable(s);
        console.log(`'${s}' ${isMatch ? "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

# 命名方式

当我们添加更多的验证器时,我们会希望有某种组织方案,这样我们就可以跟踪我们的类型,而不用担心与其他对象的名称冲突。与其把很多不同的名字放到全局命名空间中,不如把我们的对象包装成一个命名空间。

在这个例子中,我们将把所有与验证器相关的实体移到一个叫做 Validation 的命名空间中。因为我们希望这里的接口和类在命名空间之外是可见的,所以我们在它们前面加上 export。相反,变量 lettersRegexp 和 numberRegexp 是实现细节,所以它们没有被导出,也不会被命名空间以外的代码看到。在文件底部的测试代码中,我们现在需要限定在名字空间之外使用的类型的名称,例如 Validation.LettersOnlyValidator。

# 命名的验证器

namespace Validation {
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }
    const lettersRegexp = /^[A-Za-z]+$/;
    const numberRegexp = /^[0-9]+$/;
    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 } = {};
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

# 跨文件分割

随着我们的应用程序的增长,我们将希望把代码分成多个文件,以使它更容易维护。

# 多文件命名空间

在这里,我们将把我们的 Validation 命名空间分成许多文件。尽管这些文件是分开的,但它们都可以为同一个命名空间做出贡献,并且可以像在一个地方定义一样被使用。由于文件之间存在依赖关系,我们将添加引用标签来告诉编译器这些文件之间的关系。我们的测试代码在其他方面没有变化。

Validation.ts

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

LettersOnlyValidator.ts

/// <reference path="Validation.ts" />
namespace Validation {
    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

ZipCodeValidator.ts

/// <reference path="Validation.ts" />
namespace Validation {
    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

Test.ts

/// <reference path="Validation.ts" />
/// <reference path="LettersOnlyValidator.ts" />
/// <reference path="ZipCodeValidator.ts" />
// 一些测试案例
let strings = ["Hello", "98052", "101"];
// 要使用的验证器
let validators: { [s: string]: Validation.StringValidator } = {};
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

一旦涉及到多个文件,我们就需要确保所有的编译后的代码都能被加载。有两种方法可以做到这一点。

首先,我们可以使用 outFile 选项进行串联输出,将所有的输入文件编译成一个单一的 JavaScript 输出文件。

tsc --outFile sample.js Test.ts
1

编译器将根据文件中存在的参考标签自动排列输出文件。你也可以单独指定每个文件:

tsc --outFile sample.js Validation.ts LettersOnlyValidator.ts
ZipCodeValidator.ts Test.ts
1
2

另外,我们也可以使用按文件编译(默认),为每个输入文件生成一个 JavaScript 文件。如果产生了多个 JS 文件,我们就需要在网页上使用 <script> 标签,以适当的顺序加载每个发射的文件,例如:

MyTestPage.html (部分代码)

<script src="Validation.js" type="text/javascript" />
<script src="LettersOnlyValidator.js" type="text/javascript" />
<script src="ZipCodeValidator.js" type="text/javascript" />
<script src="Test.js" type="text/javascript" />
1
2
3
4

# 别名

另一个可以简化命名空间工作的方法是使用 import q = x.y.z 来为常用对象创建更短的名称。不要与用于加载模块的 import x = require("name") 语法相混淆,这种语法只是为指定的符号创建一个别名。你可以为任何类型的标识符使用这类导入(通常被称为别名),包括从模块导入创建的对象。

namespace Shapes {
    export namespace Polygons {
        export class Triangle {}
        export class Square {}
    }
}
import polygons = Shapes.Polygons;
let sq = new polygons.Square(); // 与'new Shapes.Polygons.Square()'等价
1
2
3
4
5
6
7
8

注意,我们没有使用 require 关键字;相反,我们直接从我们要导入的符号的限定名称中分配。这类似于使用 var,但也适用于导入符号的类型和命名空间的含义。重要的是,对于数值来说,导入是一个不同于原始符号的引用,所以对别名 var 的改变不会反映在原始变量上。

# 与其他JavaScript库一起工作

为了描述不是用 TypeScript 编写的库的形状,我们需要声明库所暴露的 API。因为大多数 JavaScript 库只暴露了几个顶级对象,命名空间是表示它们的一个好方法。

我们把不定义实现的声明称为「环境」。通常,这些都是在 .d.ts 文件中定义的。如果你熟悉 C/C++,你可以把它们看作是 .h 文件。让我们来看看几个例子:

D3.d.ts (简要摘录)

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;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
编辑此页 (opens new window)
#TypeScript
更新时间: 2023/09/18, 16:34:13
TypeScript Office - 模块解析
TypeScript Office - 命名空间与模块

← TypeScript Office - 模块解析 TypeScript Office - 命名空间与模块→

最近更新
01
技术随笔 - Element Plus 修改包名 原创
11-02
02
Reactor - 扩展性
11-02
03
Reactor - 最佳实践
11-02
更多文章>
Theme by Vdoing | Copyright © 2021-2024 Young Kbt | blog
桂ICP备2021009994号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式