使用說明

JavaScript 轉 TypeScript:PropTypes 變成介面

在這裡把 JavaScript 轉 TypeScript,可以省下遷移時第一輪最枯燥的工作。這個工具用語法解析器讀取你的程式碼,把 React 的 PropTypes 變成介面,從預設值取得型別,再補上能推斷出來的型別,最後交還排版好的 TypeScript。它一次處理一個檔案或一段程式碼,不會執行你的程式碼,也不會上傳任何內容。它無法得知的部分,會留給你處理。下面各節會清楚說明是哪些。


JavaScript 轉 TypeScript 的步驟

  1. 把程式碼貼到 JavaScript 或 JSX 欄位。貼上之前,欄位會顯示「在這裡貼上 JavaScript 或 JSX…」。上限是 500 萬個字元。
  2. 稍等一下。工具會在你輸入或貼上後約 0.35 秒自動轉換,所以沒有按鈕可按。
  3. 在「TypeScript」標題下查看結果;程式碼含有 JSX 時,標題是「TypeScript (TSX)」。結果以唯讀的語法標色程式碼顯示。
  4. 查看程式碼上方的提示。它們會說明做了什麼,例如「已寫出 2 個介面」或「已加上 11 個型別註記」。如果沒有任何地方需要型別,會顯示「這裡沒有需要加型別的地方,所以只重新排版了程式碼。」
  5. 選擇複製到剪貼簿。按鈕會變成「已複製」。
  6. 程式碼下方的轉換選項有兩個核取方塊:React 模式和嚴格模式。更改其中一個,程式碼就會重新轉換。

如果文字不是有效的 JavaScript,你會看到「這不是有效的 JavaScript:第 N 行第 M 欄有語法錯誤。」,並標出有問題的那一行與位置。已經含有 TypeScript 語法的程式碼會被視為無效。工具處理的是你貼上的程式碼,適合單一元件、模組或片段,不適合整個專案。

範例:使用 PropTypes 的 React 元件

輸入是一個小計數器,有 PropTypes,也有尚未加上型別的事件處理函式。轉換後會寫出介面 CounterProps:label 因為 isRequired 而是必填,start 和 onChange 則是選填。預設值 n = 1 會變成 n: number = 1,button 上的 onClick 處理函式會讓 e 取得按鈕元素用的 React.MouseEvent 型別。沒用到的 prop-types import 會被移除,Prettier 會把 JSX 排成多行。工具最後顯示已寫出 1 個介面、已加上 3 個型別註記。

沒有改變的部分:useState(start) 維持原樣,因為工具不會從值的用法去猜型別。

React PropTypes 如何變成 TypeScript 介面

開啟 React 模式後,工具會依元件的 PropTypes 寫出名為 名稱Props 的介面,放在元件上方,並用它替 props 加上型別。這適用於函式元件(宣告式、箭頭函式,以及包在 memo 裡的),也適用於有靜態 propTypes 或 Foo.propTypes = {...} 指定的類別。帶有 .isRequired 的 prop 是必填,其他的會加上 ?。prop 上方的註解會移進介面。

propTypes 敘述會被移除;如果沒有其他地方用到,prop-types 的 import 也會一併移除。類別元件還會從 this.state = {...} 得到 state 介面。沒有 PropTypes 的類別,會依它讀取的 this.props.x 建立 props 介面。沒有 PropTypes 的函式元件,只有在嚴格模式下才會得到 props 介面。

沒有 PropTypes 時補上的型別,以及嚴格模式

想從 JSX 變成 TSX,只要貼上元件即可:程式碼含有 JSX 時,結果的標題就是「TypeScript (TSX)」。嚴格模式預設關閉。開啟後可以看見所有缺口。它會在無法推斷型別的地方寫上明確的 any:let x; 變成 let x: any;,const list = [] 變成 any[],沒有型別的參數會加上 : any。關閉時,這些地方會維持沒有型別。開啟後,剩下要修正的項目就很容易搜尋。

工具不會動的內容、註解與隱私

它只讀取一段程式碼,不會亂猜。以下情況會維持原樣,或變成 any:

輸出只是第一輪,不是完成的遷移。把它貼進你的專案,執行 tsc,再手動把每個 any 改得更精確。工具不會重新命名檔案,所以請自己把元件存成 .tsx。

註解和排版都會保留:程式碼用 @babel/parser 讀取,每個型別註記都以編輯的方式插入你的原始文字,之後再由 Prettier 重新排版,並維持你的引號風格、分號和縮排寬度。解析、編輯和排版全都在你瀏覽器的 Web Worker 中進行,你的程式碼不會被上傳,也不會被執行。想在轉換前先整理程式碼,可以用程式碼美化工具;想先看懂壓縮或混淆過的指令碼,可以用 JS 反混淆工具。


常見問題

怎麼把 JavaScript 轉成 TypeScript?

把 JavaScript 或 JSX 貼到「JavaScript 或 JSX」欄位。約三分之一秒後,結果會出現在「TypeScript」標題下;程式碼含有 JSX 時,標題是「TypeScript (TSX)」。沒有轉換按鈕。用「複製到剪貼簿」就能取走結果。

可以把 React PropTypes 變成 TypeScript 介面嗎?

可以。開啟 React 模式後,每個 propTypes 物件都會變成以元件命名的介面,例如 CounterProps。帶有 isRequired 的 prop 是必填,其他的會加上問號。propTypes 敘述會被移除;如果檔案中沒有其他地方用到,prop-types 的 import 也會一併移除。它適用於函式元件,以及有靜態 propTypes 的類別。

怎麼從 JSX 變成 TSX?

貼上 JSX 元件即可。程式碼含有 JSX 時,結果的標題是「TypeScript (TSX)」,React 模式也會自動開啟,所以 props 會得到介面,處理函式會得到事件型別。工具不會重新命名檔案,請把結果以 .tsx 副檔名存進你的專案。

React 模式和嚴格模式有什麼作用?

「轉換選項」裡的 React 模式會把 PropTypes 變成介面,並替事件處理函式、props 和 Hook 加上型別。程式碼含有 JSX、react 或 prop-types 時預設開啟;關閉後,PropTypes 維持原樣。嚴格模式預設關閉,會在無法推斷型別的地方寫上明確的 any,而不是省略。

為什麼輸出裡還有 any?

只有在能從程式碼本身讀出來時,才會寫上型別。自訂的 PropTypes 驗證函式,或從其他檔案匯入的型別會變成 any,嚴格模式還會替沒有型別的變數和參數加上明確的 any。輸出只是第一輪。請用 tsc 檢查,再把 any 換成真正的型別。

為什麼回呼參數沒有加上型別?

直接傳給呼叫的參數,例如 items.map((x) => x.id) 裡的 x,是刻意維持原樣的,這樣 TypeScript 仍然可以從接收回呼的函式推斷它的型別。

我的註解和排版會保留嗎?

註解會保留,因為型別註記是以文字編輯的方式插入你的原始程式碼,而不是重新產生程式碼。之後會經過 Prettier,它會維持你的引號風格、分號和縮排寬度,但可能重新換行過長的行。PropTypes 項目上方的註解,會移到介面中對應的屬性。

我的程式碼會被上傳或執行嗎?

不會。程式碼在你瀏覽器的 Web Worker 中解析和改寫,不會傳送到伺服器,也不會被執行。如果有語法錯誤,會顯示附有行號和欄號的訊息。上限是 500 萬個字元。