本篇只會稍微提到製作聲明文件的方式,並不會有過多深入的探討。
有時候當我們使用第三方模組時,它們是依據純 JavaScript 來撰寫,這種程式碼通常不包含型別的聲明,這樣一來,TypeScript 便無法進行型別檢查,我們可能會遇到以下問題:
編譯時錯誤檢測不足
: 可能導致在編譯時沒有錯誤提示,運行時才會出現 Bug。
程式碼提示不足
: 沒有類型信息,所以編輯器沒有程式碼提示功能。
為了解決這些問題,所以我們才需要使用聲明文件。聲明文件以 .d.ts
為擴展名 ( d 的意思就是 declaration ),裡面只包含型別註解和型別定義。
因為 .d.ts 也是一個 Typescript 文件,所以我們需要到 tsconfig.json 去設定 include。例如威爾豬把 [聲明文件名稱].d.ts 放在和 tsconfig.json 同一層:
├── dist
├── src
| └── app.ts
├── math.d.ts
└── tsconfig.json
"compilerOptions": {
// ...
"allowJs": true, // 允許 JS 引入和編譯輸出
// ...
},
"include": ["src/**/*.ts", "./*.d.ts"] // 端看聲明文件要放哪來決定路徑
假設我們有一個純 JavaScript 的函式庫,它提供一個 add 函式來執行加法的操作:
// math.js
const add = (a, b) => a + b;
現在,我們希望在 TypeScript 項目中使用這個函式庫,我們可以創建一個聲明文件 math.d.ts
,其中包含函式 add 的型別註解:
// math.d.ts
declare module "math" {
export function add(a: number, b: number): number;
}
在聲明文件中使用 declare module 來描述模組的類型和對外的接口。
// app.ts
// 引入 math 模組
import { add } from "math";
add(2, "4"); // ❌ 錯誤 string 不可指派給 number 類型
現在,當我們在 TypeScript 中引入 math 模組時,TypeScript 將能夠識別並檢查 add 函式的型別,並提供相應的程式碼提示,確保程式碼的穩定性和可讀性。
我們使用 Vue 官方 的方式來安裝 Vue 3 + Vite + TypeScript + Pinia。
npm create vue@latest
安裝完後打開 src/main.ts 就會發現,剛剛安裝的 vue 跟 pinia 出現找不到模組的錯誤。
這時我們可以透過 npm 使用 @types
或 typings
來尋找是否有可用的 TypeScript 聲明文件。
npm install --save-dev @types/vue
# 或
npm i -D vue-types
安裝過程:
這樣我們找不到模組的錯誤就消失了,通常較大的框架或模組都有提供相對應的聲明文件。
npm install --save-dev @types/react @types/react-dom
所以,當我們安裝完 JavaScript 函式庫、框架和第三方模組時,發現有找不到模組的錯誤,就可以使用此方式來試著解決,但如果是一些比較小眾的套件可能就必須要自己創建了。
透過 @types 或 typings 的安裝方式,聲明文件會放置於 node_modules/@types 底下。
全域環境可以聲明變數、函式、類別、命名空間、枚舉值、類型別名和接口等,這樣就可以在任一檔案中直接使用,TypeScript 會自動識別它們的類型。
看以下範例:
// globals.d.ts
// 聲明全域變數 (也可以使用 var、let)
declare const globalVariable: string;
// 聲明全域函式
declare function globalFunction(param1: number, param2: string): void;
// 聲明全域類別
declare class GlobalClass {
constructor(public name: string);
sayHi(): string;
}
// 聲明全域命名空間
declare namespace GlobalNamespace {
let property1: number;
let property2: string;
}
// 聲明全域枚舉值
declare enum GlobalEnum {
property1,
property2,
property3,
}
// 聲明全域類型別名
declare type TGlobalType = number | string;
// 聲明全域接口
declare interface IGlobalInterface {
property1: number;
property2: string;
}
上面範例名稱、內容等都可自行依需求修改。
總之,聲明文件是 TypeScript 中的一個重要概念,它允許我們在使用 JavaScript 函式庫、框架或模組時,仍然能夠享受 TypeScript 的優勢,無論是簡單的模組還是複雜的函式庫等,聲明文件都能幫助我們更好地整合外部資源。因此當我們開始在 TypeScript 項目中使用第三方資源時,尋找適用的聲明文件來提供類型信息,使程式碼更加可靠、可讀並具有更好的程式碼提示。