typescript 類型斷言與實際類型轉換
本文探討 TypeScript 中類型轉換的常見誤區,特別是 as 關鍵字的使用。 一個開發者遇到的問題是,即使使用 as number,typeof 仍然顯示變量為字符串類型。
問題代碼如下:
const props = defineProps() getDictGroup(props.group) export const getDictGroup = async (sid: number) => { const dict = await getDict() console.info(typeof sid); // 輸出 String sid = sid as number; console.info(typeof sid); // 輸出 string console.info(typeof (sid as number)); // 輸出 string }
盡管 sid 的類型聲明為 number,但實際運行時 typeof sid 顯示為 string,as number 并沒有改變運行時的類型。
此外,使用 parseInt(sid) 會導致 TypeScript 報錯,提示無法將 number 類型賦值給 string 類型。
TypeScript 類型系統的本質
問題的關鍵在于理解 TypeScript 的類型系統。as 關鍵字是類型斷言,它只影響 TypeScript 編譯器的類型檢查,不會在運行時修改變量的實際類型。 它告訴編譯器:“我相信這個值是這個類型,請不要報錯”。 但運行時的值仍然保持不變。
實際類型轉換方法
要進行實際的類型轉換,需要使用 JavaScript 的內建函數,例如 Number()、parseInt()、parseFloat() 等。
正確的代碼示例:
const props = defineProps() getDictGroup(props.group) export const getDictGroup = async (sid: string) => { // 修改參數類型為string const dict = await getDict() console.info(typeof sid); // 輸出 string const numSid = Number(sid); // 使用 Number() 進行類型轉換 console.info(typeof numSid); // 輸出 number console.info(typeof (numSid as number)); // 輸出 number // 現在可以使用 numSid 進行后續操作 }
在這個修正后的例子中,我們首先將 sid 的類型聲明為 string,以反映其實際運行時類型。然后使用 Number(sid) 將其轉換為數字類型。 as number 仍然可以用于類型斷言,但此時它只是對已經轉換后的 numSid 進行冗余的類型斷言。
因此,在 TypeScript 中,需要區分類型斷言(as)和實際類型轉換(JavaScript 內建函數)。 as 僅僅是告訴編譯器,而實際的類型轉換需要使用 JavaScript 的函數來完成。