[英]TypeScript: Using a plain JavaScript lib in web project, with custom typings
我有一個使用 TypeScript 和 Webpack 的網站項目。 現在我需要在這個項目中使用一個外部專有的 JavaScript 庫。 這是我的項目結構:
├── dist
│ ├── foo.js
│ ├── main.js
│ └── index.html
├── src
│ ├── foo.d.ts
│ └── index.ts
├── webpack.config.js
└── tsconfig.json
文件dist/main.js
由 Webpack 生成,它使用ts-loader
編譯條目 TypeScript 文件src/index.ts
。 foo.js
和main.js
都在dist/index.html
文件中被引用,使用 html 腳本標簽:
<script src="foo.js"></script>
<script src="main.js"></script>
dist/foo.js
庫是一個普通的舊 JavaScript 文件,它不是 ES6 模塊,它只是包含一堆類。
我創建了帶有類型的foo.d.ts
文件,以幫助 TypeScript 對foo.js
中定義的類的使用進行類型檢查:
// src/foo.d.ts
export declare class MyClass {
constructor(message: string);
}
但是我無法正確注冊它,以便 TypeScript 和 Webpack 都能正確處理此設置。 問題在於 TypeScript 如何加載類型聲明文件。 如果我用相對路徑引用它,TypeScript 可以看到並使用它,但 Webpack 抱怨它無法解決它:
此index.ts
編譯,但 Webpack 給出錯誤:
import { MyClass } from './foo';
const c = new MyClass('Hello, world!');
Webpack 錯誤: Module not found: Error: Can't resolve './foo' in '/path-to/src'
Webpack 失敗的原因顯然是它正在尋找foo
代碼但未能找到它,因為編譯后的 JavaScript 包含require("./foo")
。
所以我需要替換這條線
import { MyClass } from './foo';
告訴 TypeScript 不要在編譯代碼中包含這個require()
調用。 我認為這個ts-loader 討論中描述了這個問題,但我不確定那里的最終判決是什么。 如果我這樣導入
import { MyClass } from 'foo';
TypeScript 編譯器給出錯誤Cannot find module 'foo' or its corresponding type declarations.
. 顯然,必須在tsconfig.json
中為 TypeScript 指定一些東西才能知道在哪里尋找類型聲明。 但是添加"include": ["src/**/*"]
似乎並沒有改變任何東西。
問題是你在謊報你是如何真正得到它的(嗯,不是真的,你只是不知道如何在你的.d.ts
文件中拼寫“這存在於全局范圍內”)。
在運行時,您只是依賴MyClass
存在於 scope 鏈的某個位置,因此您需要告訴 TypeScript 您正在工作的環境就是這種環境。 您這樣做的方式是使用修改全局范圍的類型定義的環境模塊聲明 - 這與您的定義非常相似,只是您不使用export
關鍵字:
// src/foo.d.ts
// Note the lack of `export` here
declare class MyClass {
constructor(message: string);
}
或者,如果您使用window.MyClass
,則使用global
聲明:
declare global {
interface Window {
MyClass: MyClass
}
}
declare class MyClass {
myMethod(): void
}
然后,在您的代碼中,您只需new MyClass("Hello world")
和 TypeScript 就會得到您的支持。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.