跳至主要內容

宣告檔案

什麼是宣告檔案?

讓我們來看看更通用的方式,有時也更方便的方式來宣告模組的類型:.flow 檔案。

有兩種可能的用例,視實作檔案是否存在而定。

在第一種情況下,模組的已匯出類型會宣告在宣告檔案 <FILENAME>.flow 中,該檔案位於與對應實作檔案 <FILENAME> 相同的目錄中。宣告檔案會完全覆蓋同置的實作。換句話說,Flow 會完全忽略 <FILENAME>,而只讀取 <FILENAME>.flow

在第二種情況下,實作檔案完全不存在。<FILENAME>.flow 會被視為命名為 <FILENAME>

請注意,.flow 副檔名適用於 .js 檔案和 .json 檔案。對應的宣告檔案副檔名分別為 .js.flow.json.flow

現在讓我們來看上面記錄的第一種情況的範例。假設我們在 src/LookBeforeYouLeap.js 檔案中有以下程式碼

import { isLeapYear } from "./Misc";
if (isLeapYear("2020")) console.log("Yay!");

假設 src/Misc.jsisLeapYear 的不相容實作

1export function isLeapYear(year: number): boolean {2  return year % 4 == 0; // yeah, this is approximate3}

如果我們現在建立宣告檔案 src/Misc.js.flow,其中的宣告會用於取代 src/Misc.js 中的程式碼。假設我們在 src/Misc.js.flow 中有以下宣告。

注意:宣告檔案中宣告的語法與我們在 建立函式庫定義 章節中所見相同。

1declare export function isLeapYear(year: string): boolean;

你認為會發生什麼事?

沒錯,src/LookBeforeYouLeap.js 中的 isLeapYear 呼叫會進行類型檢查,因為宣告檔案中的 year 參數預期為 string

正如這個範例所示,宣告檔案必須謹慎撰寫:由程式設計師負責確保宣告正確無誤,否則可能會隱藏類型錯誤。

在一般程式碼中內嵌宣告

有時,在實作檔案的原始程式碼中內嵌宣告會很有用。

在以下範例中,假設你想要完成撰寫函式 fooList,而不需要先模擬其相依性:函式 foo 會接收一個 number 並傳回一個 string,而類別 List 則有一個 map 方法。你可以透過包含 Listfoo 的宣告來執行此操作

1declare class List<T> {2  map<U>(f: (x: T) => U): List<U>;3}4declare function foo(n: number): string;5
6function fooList(ns: List<number>): List<string> {7  return ns.map(foo);8}

別忘了將宣告替換為適當的實作。