环境命名空间打字稿示例

Ambient Namespaces typescript example

Namespaces章节给出了一个与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 最让我困惑的是上面的例子使用 declare namespace ... 而不是 namespace D3 (例如 命名空间验证)。另外,declare var d3: D3.Base; 有什么用(以及如何使用?)?

此类声明定义的全局变量并非来自导入,但可能由某些 <script>window 上定义。为了能够直接使用这些变量(无需导入!),您始终可以使用引用,例如:

/// <reference path="../types/D3.d.ts" />
d3.select("div"); // No import!

如果声明文件位于 @types 目录中,则应在不明确引用的情况下将其包含在内。


命名空间使用 declare 因为这是一个声明文件:它必须导出命名空间(仅对模块有效)或声明它,以使这些类型可用。

据我了解,示例中的 "code" 不会生成或更改任何输出 javascript。所有声明都将帮助智能感知和打字稿编译器发现错误,但不会改变代码。该示例给出的声明适用于 "ambient" 声明文件,即为普通 javascript 库提供打字稿定义的声明文件,以便打字稿和智能感知可以像打字稿文件一样使用它们普通的 javascript。我相信,在第一个近似值中,打字稿会将它发现的任何它没有声明知识的东西视为 "any" 类型。

对于提到的库,您最好使用现有的类型库 (npm install --save-dev @types/d3)。我发现在安装库 (npm install --save d3) 和 @types/d3 后,在 .ts 文件中使用 import * as d3 from 'd3'(在 angular 5 中;其他情况可能会执行其他步骤)带上 object 并输入信息,一切都令人满意。如果你打开类型文件,你会看到一组与打字稿文档示例中给出的完全不同的声明,但我相信它们仍然都是声明,即没有代码。

回复编辑

示例中的文件不是主要的打字稿文件。它是一个描述普通 javascript 库的 "typescript shape" 的声明文件,即打字稿编译器和智能感知应该如何假装普通 javascript 是用打字稿编写的。虽然您可能认为选择名称 D3 是随意的,但事实并非如此。 .d.ts 文件试图为库(d3 库:https://www.npmjs.com/package/d3)提供打字稿元信息,而该库本身并不提供该信息(尽管如前所述,该特定库的打字稿元信息是作为@types 包提供)。

如果您正在编写自己的库代码并希望按照验证示例在命名空间内工作,您将使用 namespace D3 而不是 declare namespace D3,但您也将编写一个 .ts 文件,而不是 .d.ts 文件。正如文档的章节标题所说,该示例正在处理 ambient 命名空间,即文件编写者(通常)不提供的普通 javascript 代码的命名空间。

总而言之,两部分文档的目标是不同的。在前半部分,"validation" 代码向您展示了如何在您自己的打字稿代码中使用名称空间。在下半部分,"d3" 代码向您展示了如何为普通 javascript 而不是 typescript 的代码提供 typescript 元数据。