命名空间vs模块与打字稿中的打字?

时间:2017-06-12 07:13:24

标签: typescript

有人可以通过一个例子来解释这些概念之间的区别,我真的很困惑,当它们都服务于同一目的时,使用其中三个是什么?

1 个答案:

答案 0 :(得分:21)

TL; DR

模块和命名空间是两种封装方式 - 将代码分解为有意义的部分。新代码应该用模块而不是命名空间编写。

声明文件(" typings")用于描述模块,命名空间,变量,类型声明等,而不实际包含任何可运行的代码。声明文件只是告诉TypeScript存在的内容,以及如何使用这些内容。

针对不同包的DefinitelyTyped主机声明文件。名为foo-bar的DefinitelyTyped包的声明文件将在npm上发布为@types/foo-bar

命名空间

这些在JavaScript中形式化了一种过时的模式。该模式基本上是将代码包装在IIFE中,以防止全局范围内的声明冲突。这些东西加上了'#34;出口"在一个对象上并将它们分配给一个变量(希望)在全局范围内具有唯一的名称,如$_或其他。

举个例子:

namespace foo {
    export var x = 10;
    export var y = 20;
}

这会发出

var foo;
(function (foo) {
    foo.x = 10;
    foo.y = 20;
})(foo || (foo = {}));

命名空间具有其他有用的属性,例如能够与函数,类或其他命名空间合并。但主要是,它们是在过渡时期引入的,在此期间必须提供组织代码的两种主要方式:在全局范围内的一个众所周知的变量上提供API表面(例如$,{{1} },_)或...

模块

这些一下子描述了ECMAScript(标准JavaScript),CommonJS(即Node.js),AMD(即Require.js)和System.js模块。这个想法的关键在于,不是仅仅将变量放入全局范围并希望它们不会发生冲突,而是每个文件都有自己独特的范围并且具有导出。

实际上,模块的原始实现(CommonJS,AMD,System.js)的工作方式相同:将代码包装在函数中以获取正确的范围,并将属性粘贴到对象上。

但TypeScript允许您编写代码,就好像您使用顶级angular语句编写ECMAScript模块一样。基本上,对于TypeScript,任何顶级exportimport s的文件都是模块。

例如,以下

export

转换为以下CommonJS模块:

export var x = 10;
export var y = 20;

虽然命名空间有一些有用的用例,但模块已经成为将代码分解成不同部分的明确方法。

分型/类型

"分型"是"use strict"; Object.defineProperty(module.exports, "__esModule", { value: true }); module.exports.x = 10; module.exports.y = 20; 成为获取声明文件的规定方式之前的声明文件(.d.ts文件)的包管理器(很快就会有更多内容)

结果,"打字"也已成为声明文件的昵称。

如果您要开始新项目,请勿使用“打字”。 TypeScript生态系统在很大程度上标准化了将npm用于声明文件。 此外,由于术语混淆,您可能不应该调用声明文件" typings"。

话虽如此,我们可以进入以下主题:

声明文件

声明文件(@types文件,也称为定义文件)是描述现有代码的TypeScript文件。可以使用.d.ts标志从.ts文件生成它们,也可以手动创建它们来描述现有的JavaScript代码。

声明文件包含它们实际描述的代码的声明。更具体地说,是以下TypeScript函数:

--declaration

将通过以下声明来描述:

function foo(x: number, y: number) {
    return x * 100 + y;
}

如果原始声明是用JavaScript编写的,那么仍然可以使用带有上述显式类型的声明来描述它。

这很重要,因为绝大多数JavaScript代码最初都是在TypeScript中编写的。因此社区聚集在一起并创建了一个名为DefinitelyTyped的声明文件存储库。

DefinitelyTyped

这是一个很大的git存储库,在撰写本文时描述了超过3000个库。用户可以发送修复和新包的拉取请求。

You can take a look at the repo here on GitHub

declare function foo(x: number, y: number): number 和npm

这是你如何从DefinitelyTyped获取声明文件。例如,如果你想要lodash的@types文件,你可以写

.d.ts

这些如何相关?

不幸的是,这里的想法很微妙。声明文件可以描述TypeScript中的所有内容。这意味着他们可以描述模块的外观,以及命名空间的外观。

因此,声明文件与模块和命名空间的用途不同。但是当名称空间和模块存在时,它们会向TypeScript描述,以及如何使用它们。

基本上,如果您需要使用看起来像模块或命名空间的东西而且它是用JS编写的,那么您需要一个声明文件。

即使它是用TypeScript编写的,如果它已编译为npm install @types/lodash ,那么您需要一个相应的.js文件才能使用它。

我仍然不理解

希望这有助于解释,但如果没有,请查看