Ambient Namespaces TypeScript 範例
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;
我真正不明白的是,我如何在我的模組或 TypeScript 腳本中使用 D3.d.ts?請給我一些簡短的範例。
編輯
請忽略這裡使用的是 D3 的事實;也可以是 B3 或 G3 或 X7 ... 無所謂;我對特定的函式庫不感興趣。我只對 如何使用所給的範例在我的 TypeScript 模組和 TypeScript 腳本中使用感興趣。
EDIT2 最讓我困惑的是,上面的例子使用了 declare namespace ...,而不是 namespace D3(例如 namespace Validation 就是這樣使用的)。另外,declare var d3: D3.Base; 的用途是什麼(以及如何使用?)?
答案#1
這些宣告定義了全域變數,這些變數不是來自匯入(imports),但可能會被某些 <script> 在 window 上定義。為了能夠直接使用這些變數(不需要匯入!),你可以總是使用一個參考,例如:
/// <reference path="../types/D3.d.ts" />
d3.select("div"); // No import!
如果宣告檔案被放置在 @types 目錄中,應該不需要明確引用就會被包含。
這個命名空間使用 declare,因為這是一個宣告檔:它必須要麼導出這個命名空間(這僅對模組有效),要麼宣告它,以使這些類型可用。
答案#2
據我對 TypeScript 的理解,範例中的「程式碼」並不會生成或改變任何輸出的 JavaScript。它全都是宣告,這些宣告將幫助 Intellisense 和 TypeScript 編譯器發現錯誤,但不會對程式碼本身作任何修改。範例中提供的宣告是用於「環境(ambient)」宣告檔,也就是提供 TypeScript 定義給普通的 JavaScript 函式庫,讓 TypeScript 和 Intellisense 可以像操作 TypeScript 檔案一樣操作它們,而不是只當作純 JavaScript。我相信,初步來說,TypeScript 對於那些沒有宣告知識的任何東西,都會視為「any」類型。
對於提到的這個函式庫,你最好使用現有的型別函式庫(npm install --save-dev @types/d3)。我發現,在安裝了函式庫(npm install --save d3)和 @types/d3 之後,在 .ts 檔案中使用 import * as d3 from 'd3'(在 Angular 5 中;其他情況可能需要其他步驟)會將物件和型別資訊引入,而且一切運作良好。如果你打開型別檔案,你會看到一套與 TypeScript 文件範例中提供的完全不同的宣告,但我相信它們仍然都是宣告,也就是說,沒有程式碼。
回覆編輯
範例中的檔案不是主要的 TypeScript 檔案。它是一個宣告檔案,用來描述普通 JavaScript 函式庫的「TypeScript 形狀」,也就是 TypeScript 編譯器和 IntelliSense 應該如何假裝普通的 JavaScript 如果用 TypeScript 重寫會是什麼樣子。雖然你可能認為 D3 這個名稱的選擇是隨意的,但並不完全是。這個 .d.ts 檔案試圖為一個函式庫提供 TypeScript 的元資訊(d3 函式庫:https://www.npmjs.com/package/d3),該函式庫本身並未提供這些資訊(儘管如前所述,該特定函式庫的 TypeScript 元資訊可作為 @types 套件取得)。
如果你正在編寫自己的函式庫程式碼,並希望按照驗證範例在命名空間中工作,你會使用 namespace D3 而不是 declare namespace D3,但你同時也會編寫一個 .ts 檔案,而不是 .d.ts 檔案。正如文件章節標題所說,那個範例是在操作 環境 命名空間,也就是說,是為了普通的 JavaScript 程式碼而設計的命名空間,而該檔案的編寫者通常不會提供這些命名空間。
總結來說,文件的前後兩部分目標不同。在前半部分,「validation」代碼向你展示如何在你自己的 TypeScript 代碼中使用命名空間。在後半部分,「d3」代碼向你展示如何為純 JavaScript(不是 TypeScript)的代碼提供 TypeScript 元數據。
