發布

現在您已按照本指南的步驟撰寫宣告檔案,是時候將其發布到 npm 了。您可以透過兩種主要方式將宣告檔案發布到 npm

  1. 與您的 npm 套件綑綁
  2. 發布到 npm 上的 @types 組織

如果您的類型是由您的原始碼產生的,請將類型與您的原始碼一起發布。TypeScript 和 JavaScript 專案都可以透過 declaration 產生類型。

否則,我們建議將類型提交給 DefinitelyTyped,它會將類型發布到 npm 上的 @types 組織。

在 npm 套件中包含宣告

如果您的套件有一個主 .js 檔案,您也需要在 package.json 檔案中指出主宣告檔案。將 types 屬性設定為指向您的已套件化宣告檔案。例如

json
{
"name": "awesome",
"author": "Vandelay Industries",
"version": "1.0.0",
"main": "./lib/main.js",
"types": "./lib/main.d.ts"
}

請注意,"typings" 欄位與 types 同義,也可以使用。

相依性

所有相依性都由 npm 管理。請確定您依賴的所有宣告套件都已在 package.json"dependencies" 區段中適當地標記。例如,假設我們撰寫了一個使用 Browserify 和 TypeScript 的套件。

json
{
"name": "browserify-typescript-extension",
"author": "Vandelay Industries",
"version": "1.0.0",
"main": "./lib/main.js",
"types": "./lib/main.d.ts",
"dependencies": {
"browserify": "latest",
"@types/browserify": "latest",
"typescript": "next"
}
}

在此,我們的套件依賴於 browserifytypescript 套件。browserify 沒有將其宣告檔案與其 npm 套件一起套件化,因此我們需要依賴 @types/browserify 來取得其宣告。另一方面,typescript 會套件化其宣告檔案,因此不需要任何其他相依性。

我們的套件公開了來自每個套件的宣告,因此我們 browserify-typescript-extension 套件的任何使用者也需要有這些相依性。因此,我們使用 "dependencies" 而不是 "devDependencies",否則我們的使用者將需要手動安裝這些套件。如果我們只是撰寫一個命令列應用程式,而不是預期我們的套件會被用作函式庫,我們可能會使用 devDependencies

警示

/// <reference path="..." />

不要在宣告檔案中使用 /// <reference path="..." />

ts
/// <reference path="../typescript/lib/typescriptServices.d.ts" />
....

改用 /// <reference types="..." />

ts
/// <reference types="typescript" />
....

請務必重新檢閱 消耗相依性 部分以取得更多資訊。

封裝相依宣告

如果您的類型定義相依於其他套件

  • 不要將其與您的類型定義合併,請將每個類型定義保留在自己的檔案中。
  • 不要複製套件中的宣告。
  • 相依於 npm 類型宣告套件,如果它未封裝其宣告檔案。

使用 typesVersions 進行版本選取

當 TypeScript 開啟一個 package.json 檔案以找出它需要讀取哪些檔案時,它首先會查看一個名為 typesVersions 的欄位。

資料夾重新導向(使用 *

具有 typesVersions 欄位的 package.json 可能如下所示

json
{
"name": "package-name",
"version": "1.0.0",
"types": "./index.d.ts",
"typesVersions": {
">=3.1": { "*": ["ts3.1/*"] }
}
}

package.json 告訴 TypeScript 首先檢查 TypeScript 的目前版本。如果是 3.1 或更新版本,TypeScript 會找出您相對於套件匯入的路徑,並從套件的 ts3.1 資料夾中讀取。

這就是 { "*": ["ts3.1/*"] } 的意思 - 如果你熟悉 路徑對應,它的運作方式完全相同。

在上述範例中,如果我們從 "package-name" 匯入,TypeScript 會嘗試在 TypeScript 3.1 中執行時從 [...]/node_modules/package-name/ts3.1/index.d.ts(和其他相關路徑)解析。如果我們從 package-name/foo 匯入,我們會嘗試尋找 [...]/node_modules/package-name/ts3.1/foo.d.ts[...]/node_modules/package-name/ts3.1/foo/index.d.ts

如果我們不在此範例中執行 TypeScript 3.1 呢?好吧,如果 typesVersions 中沒有任何欄位相符,TypeScript 會回退到 types 欄位,因此這裡的 TypeScript 3.0 和更早版本將重新導向到 [...]/node_modules/package-name/index.d.ts

檔案重新導向

當您只想變更單一檔案的解析度時,您可以透過傳入確切的檔案名稱來告訴 TypeScript 以不同的方式解析檔案

json
{
"name": "package-name",
"version": "1.0.0",
"types": "./index.d.ts",
"typesVersions": {
"<4.0": { "index.d.ts": ["index.v3.d.ts"] }
}
}

在 TypeScript 4.0 及以上版本中,"package-name" 的匯入將解析為 ./index.d.ts,而在 3.9 及以下版本中則解析為 "./index.v3.d.ts

請注意,重新導向僅影響套件的外部 API;專案內的匯入解析不受 typesVersions 影響。例如,前一個範例中的 d.ts 檔案包含 import * as foo from "./index" 仍會對應到 index.d.ts,而不是 index.v3.d.ts,而匯入 import * as foo from "package-name" 的另一個套件取得 index.v3.d.ts

比對行為

TypeScript 決定編譯器和語言版本是否相符的方式是使用 Node 的 semver 範圍

多個欄位

typesVersions 可以支援多個欄位,其中每個欄位名稱由要比對的範圍指定。

{
"name": "package-name",
"version": "1.0",
"": "./index.d.ts",
"typesVersions": {
">=3.2": { "*": ["ts3.2/*"] },
">=3.1": { "*": ["ts3.1/*"] }
}
}

由於範圍有可能重疊,因此決定套用哪個重新導向具有特定順序。這表示在上述範例中,即使 >=3.2>=3.1 比對器都支援 TypeScript 3.2 及以上版本,但反轉順序可能會產生不同的行為,因此上述範例不等於以下範例。

{
"name": "package-name",
"version": "1.0",
"": "./index.d.ts",
"typesVersions": {
// NOTE: this doesn't work!
">=3.1": { "*": ["ts3.1/*"] },
">=3.2": { "*": ["ts3.2/*"] }
}
}

發佈至 @types

@types 組織下的套件會使用 types-publisher 工具DefinitelyTyped 自動發佈。若要將您的宣告發佈為 @types 套件,請向 DefinitelyTyped 提交拉取要求。您可以在 貢獻指南頁面 找到更多詳細資訊。

TypeScript 文件是一個開放原始碼專案。透過 傳送 Pull Request ❤ 協助我們改善這些頁面

此頁面的貢獻者
MHMohamed Hegazy (55)
OTOrta Therox (21)
MBMateusz Burzyński (2)
RVRauno Viskus (2)
RCRyan Cavanaugh (2)
19+

最後更新:2024 年 3 月 21 日