在 TypeScript 2.0 中,如何為在 @types npm 命名空間(DefinitelyTyped 倉庫)中不可用的模組擁有單一的聲明文件?
在一個 TypeScript 專案中,我需要使用 bytewise npm 模組。這個套件在 DefinitelyTyped npm 命名空間中沒有類型定義,所以我無法使用 TypeScript 文件中描述的方法:
npm install --save-dev @types/bytewise
由於這個模組沒有類型宣告,因此無法使用它,因為 tsc 會報錯:error TS2307: Cannot find module 'bytewise'。
為了解決這個問題,我為 bytewise 編寫了一個聲明文件,並將其添加到 node_modules/@types/bytewise/index.d.ts,這完美地解決了問題。
然而,這是一個繁瑣且常見的模式:我使用一個沒有 @types 聲明的小型 npm 庫,在 node_modules/@types 下創建一個目錄,添加一個包含該庫聲明的 index.d.ts,然後 git 強制添加該文件(因為默認情況下 node_modules 會被忽略)。
很明顯,我並不打算永遠在我的私人 node_modules 目錄下維護那些聲明,最終我希望能把它們貢獻回 DefinitelyTyped,以便以後可以更輕鬆地安裝,但我不想為我使用的每個庫創建單獨的目錄/文件,我更希望在項目根目錄有一個包含所有在 npm 上不可用聲明的單一 vendor.d.ts 文件。大概像這樣(這是我目前在項目中的情況):
import bl = require("bl");
import {Stream} from "stream";
declare module "bytewise" {
export function encode(val: any): bl;
export function decode(val: bl): any;
export const buffer: boolean;
export const type: string;
}
declare module "JSONStream" {
export function parse(patternOrPath?: string): Stream;
export function stringify(open?: string, sep?: string, close?: string);
}
問題是:我如何讓這些聲明對我專案中的所有檔案可用?我已經嘗試修改 tsconfig.json,在入口點之前包含它:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"noImplicitAny": false,
"removeComments": true,
"preserveConstEnums": true,
"outDir": "out",
"sourceMap": true
},
"files": [
"vendor.d.ts",
"index.ts"
]
}
但在我有 import * as bytewise from "bytewise"; 的檔案中,仍然會得到 error TS2307: Cannot find module 'bytewise'.。我也嘗試添加指向 vendor.d.ts 的 /// <reference path="..." /> 註解,但仍然得到相同的錯誤。我是否真的需要為每個 npm 模組都有一個單獨的宣告檔案,還是我漏掉了什麼?
答案#1
只需在您的專案中包含 vendor.d.ts,無需特殊配置,但有一個關鍵更改:將最上面的兩個匯入移到該行之後
declare module "bytewise" {
任何未經申報的出口或進口都會使這失敗,並出現類似以下的神秘訊息:
Error:(3, 16) TS2665:Invalid module name in augmentation. Module 'bytewise' resolves to an untyped module at 'my-project/node_modules/bytewise/bytewise.js'.