当前位置:网站首页>LayaBox---TypeScript---命名空间和模块
LayaBox---TypeScript---命名空间和模块
2022-08-02 10:01:00 【格拉格拉】
目录
1.介绍
我们先来写一段程序并将在整篇文章中都使用这个例子。
所有的验证器都放在一个文件里
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);
}
}
// Some samples to try
let strings = ["Hello", "98052", "101"];
// Validators to use
let validators: { [s: string]: StringValidator; } = {};
validators["ZIP code"] = new ZipCodeValidator();
validators["Letters only"] = new LettersOnlyValidator();
// Show whether each string passed each validator
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 }'.`);
}
}2.命名空间
随着更多验证器的加入,我们需要一种手段来组织代码,以便于在记录它们类型的同时还不用担心与其它对象产生命名冲突。
2.1使用命名空间的验证器
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);
}
}
}
// Some samples to try
let strings = ["Hello", "98052", "101"];
// Validators to use
let validators: { [s: string]: Validation.StringValidator; } = {};
validators["ZIP code"] = new Validation.ZipCodeValidator();
validators["Letters only"] = new Validation.LettersOnlyValidator();
// Show whether each string passed each validator
for (let s of strings) {
for (let name in validators) {
console.log(`"${ s }" - ${ validators[name].isAcceptable(s) ? "matches" : "does not match" } ${ name }`);
}
}3.分离到多文件
当应用变得越来越大时,我们需要将代码分离到不同的文件中以便于维护。
3.1 多文件的命名空间
现在,我们把Validation命名空间分割成多个文件。 尽管是不同的文件,它们仍是同一个命名空间,并且在使用的时候就如同它们在一个文件中定义的一样。 因为不同文件之间存在依赖关系,所以我们加入了引用标签来告诉编译器文件之间的关联。
---------Validation.ts--------------------------------------------
namespace Validation {
export interface StringValidator {
isAcceptable(s: string): boolean;
}
}
------------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);
}
}
}
-------------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);
}
}
}
-------------Test.ts------------------------------------------------
/// <reference path="Validation.ts" />
/// <reference path="LettersOnlyValidator.ts" />
/// <reference path="ZipCodeValidator.ts" />
// Some samples to try
let strings = ["Hello", "98052", "101"];
// Validators to use
let validators: { [s: string]: Validation.StringValidator; } = {};
validators["ZIP code"] = new Validation.ZipCodeValidator();
validators["Letters only"] = new Validation.LettersOnlyValidator();
// Show whether each string passed each validator
for (let s of strings) {
for (let name in validators) {
console.log(`"${ s }" - ${ validators[name].isAcceptable(s) ? "matches" : "does not match" } ${ name }`);
}
}当涉及到多文件时,我们必须确保所有编译后的代码都被加载了。
我们有两种方式。
第一种方式,把所有的输入文件编译为一个输出文件,需要使用--outFile标记:
tsc --outFile sample.js Test.ts
编译器会根据源码里的引用标签自动地对输出进行排序。你也可以单独地指定每个文件。
tsc --outFile sample.js Validation.ts LettersOnlyValidator.ts ZipCodeValidator.ts Test.ts第二种方式,我们可以编译每一个文件(默认方式),那么每个源文件都会对应生成一个JavaScript文件。
然后,在页面上通过 <script>标签把所有生成的JavaScript文件按正确的顺序引进来,
比如:
MyTestPage.html (excerpt)
<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" />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;
// Same as "new Shapes.Polygons.Square()"
let sq = new polygons.Square();️注意:
1.我们并没有使用
require关键字,而是直接使用导入符号的限定名赋值。2.这与使用
var相似,但它还适用于类型和导入的具有命名空间含义的符号。3.重要的是,对于值来讲,
import会生成与原始符号不同的引用,所以改变别名的var值并不会影响原始变量的值。
5.使用其它的JavaScript库
5.1 外部明明空间
流行的程序库D3在全局对象d3里定义它的功能。 因为这个库通过一个 <script>标签加载(不是通过模块加载器),它的声明文件使用内部模块来定义它的类型。 为了让TypeScript编译器识别它的类型,我们使用外部命名空间声明。
比如:
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;6.命名空间和模块
命名空间是位于全局命名空间下的一个普通的带有名字的JavaScript对象。
它们可以在多文件中同时使用,并通过
--outFile结合在一起。 命名空间是帮你组织Web应用不错的方式,你可以把所有依赖都放在HTML页面的<script>标签里。
模块像命名空间一样,可以包含代码和声明。 不同的是模块可以 声明它的依赖。
模块会把依赖添加到模块加载器上(例如CommonJs / Require.js)。模块也提供了更好的代码重用,更强的封闭性以及更好的使用工具进行优化。
7. 命名空间和模块的陷阱
7.1 对模块使用
一个常见的错误是使用/// <reference>引用模块文件,应该使用import。 要理解这之间的区别,我们首先应该弄清编译器是如何根据 import路径(例如,import x from "...";或import x = require("...")里面的...,等等)来定位模块的类型信息的。
编译器首先尝试去查找相应路径下的.ts,.tsx再或者.d.ts。 如果这些文件都找不到,编译器会查找 外部模块声明。 回想一下,它们是在 .d.ts文件里声明的。
------------------------myModules.d.ts---------------------
// In a .d.ts file or .ts file that is not a module:
declare module "SomeModule" {
export function fn(): string;
}
//----------myOtherModule.ts---------------------------------
/// <reference path="myModules.d.ts" />
import * as m from "SomeModule";这里的引用标签指定了外来模块的位置。 这就是一些TypeScript例子中引用 node.d.ts的方法。
7.2 不必要的命名空间
如果你想把命名空间转换为模块,它可能会像下面这个文件一件:
---------------shapes.ts--------------------------------------------
export namespace Shapes {
export class Triangle { /* ... */ }
export class Square { /* ... */ }
}
顶层的模块Shapes包裹了Triangle和Square。 对于使用它的人来说这是令人迷惑和讨厌的:
--------------shapeConsumer.ts-------------------------------------
import * as shapes from "./shapes";
let t = new shapes.Shapes.Triangle(); // shapes.Shapes?不应该对模块使用命名空间,使用命名空间是为了提供逻辑分组和避免命名冲突。 模块文件本身已经是一个逻辑分组,并且它的名字是由导入这个模块的代码指定,所以没有必要为导出的对象增加额外的模块层。
下面是改进的例子:
------------shapes.ts--------------------------
export class Triangle { /* ... */ }
export class Square { /* ... */ }
---------shapeConsumer.ts----------------------
import * as shapes from "./shapes";
let t = new shapes.Triangle();7.3 模块的取舍
就像每个JS文件对应一个模块一样,TypeScript里模块文件与生成的JS文件也是一一对应的。 这会产生一种影响,根据你指定的目标模块系统的不同,你可能无法连接多个模块源文件。 例如当目标模块系统为 commonjs或umd时,无法使用outFile选项,但是在TypeScript 1.8以上的版本能够使用outFile当目标为amd或system。
边栏推荐
- Do you agree with this view?Most businesses are digitizing just to ease anxiety
- 2022.7.25-7.31 AI行业周刊(第108期):值钱比赚钱更重要
- npm ERR! 400 Bad Request - PUT xxx - Cannot publish over previously published version “1.0.0“.
- TimerTask(addin timer语音)
- 剑指offer专项突击版第17天
- Naive Bayesian Method of Li Hang's "Statistical Learning Methods" Notes
- Facebook's automated data analysis solution saves worry and effort in advertising
- 8月份的.NET Conf 活动 专注于 .NET MAUI
- 李航《统计学习方法》笔记之朴素贝叶斯法
- 利用二维数据学习纹理三维网格生成(CVPR 2020)
猜你喜欢

Shell script realizes multi-select DNS simultaneous batch resolution of domain name IP addresses (new update)

适配器模式适配出栈和队列及优先级队列

【OpenCV】-霍夫变换

用汇编实现爱心特效【七夕来袭】

STL中list实现

你好,我的新名字叫“铜锁/Tongsuo”

Naive Bayesian Method of Li Hang's "Statistical Learning Methods" Notes

MSYS2 QtCreator Clangd 代码分析找不到 mm_malloc.h的问题补救

Supervised learning of Li Hang's "Statistical Learning Methods" Notes

一文带你了解推荐系统常用模型及框架
随机推荐
WPF 截图控件之文字(七)「仿微信」
软件测试之发现和解决bug
牛客刷题——剑指offer(第三期)
Pytorch的LSTM参数解释
system_error错误处理库学习
用汇编实现爱心特效【七夕来袭】
斯皮尔曼相关系数
【OpenCV】-霍夫变换
第15章 泛型
后管实现面包屑功能
Use compilation to realize special effects of love
yolov7 innovation point
Implementation of mysql connection pool
使用scrapy 把爬到的数据保存到mysql 防止重复
The R language uses the rollapply function in the zoo package to apply the specified function to the time series in a rolling manner and the window moves, and set the align parameter to specify that t
行为型模式-模板方法模式
MSYS2 QtCreator Clangd 代码分析找不到 mm_malloc.h的问题补救
周鸿祎称微软抄袭 360 安全模式后发文否认;英特尔CEO基辛格回应市值被AMD超越:股价下跌是咎由自取|极客头条...
一款优秀的中文识别库——ocr
众城优选系统开发功能