命名空间一章给出了一个与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;
我真正不明白的是如何在模块或打字稿脚本中使用D3.d.ts?请给我一些简短的例子。
编辑
请忽略这里使用 D3 的事实; 可能是 B3 或 G3 或 X7 ...无论什么;我对特定的库不感兴趣。我只对如何在打字稿模块和打字稿脚本中使用给出的示例感兴趣。
EDIT2最让我困惑的是,上面的例子使用声明命名空间......而不是命名空间D3(例如用于命名空间验证)。还有声明vard3:D3的用途(以及如何使用?)。基地;?
此类声明定义了全局变量,这些全局变量不是来自导入,但可能由某些<script>
在window
上定义。为了能够直接使用这些变量(无需导入!),您可以随时使用引用,例如:
/// <reference path="../types/D3.d.ts" />
d3.select("div"); // No import!
如果声明文件放在@types
目录中,则应包含它而不显式引用。
命名空间使用declare
,因为这是一个声明文件:它必须导出命名空间(仅对模块有效)或声明它,以使这些类型可用。
据我了解,打字稿中的"代码"不会生成或更改任何输出 JavaScript。所有声明都将帮助智能感知和打字稿编译器查找错误,但不会改变代码。该示例给出的声明用于"环境"声明文件,即为普通 javascript 库提供打字稿定义的声明文件,以便打字稿和智能感知可以像打字稿文件而不是纯 javascript 一样使用它们。我相信,在第一次近似时,打字稿将它发现的任何没有声明知识的东西都视为"任何"类型。
对于提到的库,最好使用现有的类型库(npm install --save-dev @types/d3
)。我发现在安装库(npm install --save d3
)和@types/d3
后,在.ts文件中使用import * as d3 from 'd3'
(在角度5中;其他情况可能是其他步骤)将引入对象和类型信息,并且一切工作令人满意。如果您打开类型文件,您将看到一组与打字稿文档示例中给出的声明完全不同的声明集,但我相信它们仍然是所有声明,即没有代码。
回复编辑
示例中的文件不是主打字稿文件。它是一个声明文件,描述了普通JavaScript库的"打字稿形状",即打字稿编译器和智能感知应该如何假装普通的javascript看起来像是用打字稿编写的。虽然您可能认为名称 D3 的选择是任意的,但事实并非如此。.d.ts
文件试图为一个库(d3 库:https://www.npmjs.com/package/d3)提供打字稿元信息,而该库本身并不提供该信息(尽管如前所述,该特定库的打字稿元信息可作为@types包提供)。
如果您正在编写自己的库代码并希望按照验证示例在命名空间内工作,您将使用namespace D3
而不是declare namespace D3
,但您还将编写.ts
文件,而不是.d.ts
文件。正如文档的部分标题所说,该示例正在处理环境命名空间,即文件编写者(通常)不提供的普通 JavaScript 代码的命名空间。
总之,文档的两半目标是不同的。在前半部分,"验证"代码向您展示如何在您自己的打字稿代码中使用命名空间。在后半部分,"d3"代码向您展示如何为纯JavaScript而不是打字稿的代码提供打字稿元数据。
declare namespace 关键字主要用于扩展或修改现有命名空间,通常在外部库或类型声明文件的上下文中。在这种情况下,声明命名空间块中的所有成员都将自动被其他文件访问以供引用。
另一方面,命名空间关键字用于定义新的命名空间。在这种情况下,默认情况下,命名空间内定义的成员不会向外部公开。您需要显式使用 export 关键字,以使所需的成员可访问以在其他文件中引用。
总之,声明命名空间用于修改或扩展现有命名空间,并且所有成员都自动向外部公开。 命名空间用于定义新的命名空间,您需要手动导出成员以使其在外部可访问。
我希望这能澄清声明命名空间和命名空间之间的区别!