首頁 > web前端 > js教程 > TypeScript 陷阱:開發人員常犯的錯誤以及如何避免它們

TypeScript 陷阱:開發人員常犯的錯誤以及如何避免它們

Mary-Kate Olsen
發布: 2024-11-08 06:38:02
原創
814 人瀏覽過

TypeScript Traps: Top Mistakes Developers Make and How to Dodge Them

介紹

TypeScript 已成為開發人員的熱門選擇,因為它為 JavaScript 添加了額外的功能,例如類型檢查,這有助於在程式碼運行之前捕獲錯誤。透過確保每個變數都有特定的類型,TypeScript 可以幫助防止常見錯誤,並使程式碼更易於理解和使用,尤其是在大型專案中。

然而,當人們開始學習 TypeScript 時,他們經常會遇到一些常見的問題。這些錯誤可能會使程式碼更難閱讀或導致 TypeScript 應該幫助避免的錯誤。了解這些錯誤以及如何避免它們可以對程式碼品質產生巨大的影響。它可以幫助您編寫更清晰、更安全的程式碼,並節省以後的偵錯時間。本指南將引導您解決最常見的 TypeScript 錯誤,並為您提供避免這些錯誤的實用技巧。

錯誤#1:濫用型別斷言

什麼是型別斷言?

在 TypeScript 中,型別斷言 是告訴 TypeScript「相信我,我知道這個變數應該是什麼類型」的一種方式。例如,如果 TypeScript 不確定某物是哪種類型,您可以使用類型斷言使其表現為某種類型。

這是一個簡單的例子:

let value: any = "Hello, world!";
let stringLength = (value as string).length;
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

在本例中,我們告訴 TypeScript,“我知道該值是一個字串”,因此 TypeScript 允許我們在其上使用字串功能(例如 .length)。

類型斷言的常見問題

雖然類型斷言很有幫助,但如果濫用它們也可能會導致問題。當您在沒有適當檢查的情況下強制 TypeScript 將變數視為某種類型時,可能會導致程式碼中出現錯誤,特別是當該類型實際上與您認為的不同時。

例如:

let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

在這裡,我們告訴 TypeScript value 是一個字串,但實際上,它是一個數字。這在 TypeScript 中不會顯示錯誤,但在程式碼實際執行時會出現問題,導致意外的執行階段錯誤。

為什麼過度使用型別斷言會帶來風險

過度使用型別斷言可能會產生問題,因為 TypeScript 失去了一些捕捉錯誤的能力。類型斷言告訴 TypeScript 「忽略」某些東西實際上是什麼類型,這可能會破壞使用 TypeScript 的初衷。 TypeScript 旨在幫助捕獲錯誤,但如果我們繼續斷言類型,它可能會錯過問題並讓錯誤溜走。

如何避免這個錯誤

  1. 盡可能使用型別推論:TypeScript 通常可以自行找出型別。讓 TypeScript 盡可能推斷類型,而不是使用斷言。

  2. 避免不必要地使用any:any 類型可能會讓人傾向於使用類型斷言,但any 會消除類型安全性。請改用特定類型,這樣可以減少斷言的需要。

  3. 在類型斷言之前加上檢查:如果您不確定類型,請先檢查它。例如:

let value: any = "Hello, world!";
let stringLength = (value as string).length;
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
  1. 使用unknown代替any:未知類型比任何類型都更安全,因為TypeScript要求您在使用它之前檢查類型,有助於避免不安全的斷言。

類型斷言可能是有用的工具,但應謹慎且謹慎地使用它們。透過遵循這些最佳實踐,您可以使 TypeScript 程式碼更加可靠並降低運行時錯誤的風險。

錯誤 #2:過度使用 any 類型

什麼是任何類型?

在 TypeScript 中,any 類型是告訴 TypeScript「我不知道也不關心這是什麼類型」的一種方式。當您將變數的類型設為 any 時,TypeScript 將停止檢查該變數的類型。這意味著您可以用它做幾乎任何事情——將它用作字串、數字、物件等——而 TypeScript 不會拋出任何錯誤。

範例:

let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

為什麼任何一個都會引起問題

雖然任何看起來都有幫助,但它可能會導致問題,因為它關閉 TypeScript 的安全功能。 TypeScript 的全部意義在於透過確保您使用正確的類型來幫助捕獲錯誤。但是當您使用任何變數時,TypeScript 無法檢查該變數是否有錯誤,這可能會導致錯誤。

例如:

   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

在這種情況下,因為 value 是 any,即使 value 是數字,TypeScript 也允許 value.toUpperCase(),這會在您嘗試執行程式碼時導致錯誤。

開發人員使用任何的常見原因

  1. 快速修復:有時,開發人員會將類型設定為任何只是為了使錯誤快速消失。
  2. 不確定類型:當資料類型不清楚時,開發人員可能會使用any而不是找出正確的類型。
  3. 複雜資料:如果資料很複雜,例如具有多個屬性的 API 回應,開發人員可以使用任何資料來避免輸入結構。

雖然在這些情況下使用 any 可能看起來更容易,但從長遠來看,它常常會導致更大的問題。

如何避免過度使用任何

  1. 使用unknown代替any:unknown類型更安全,因為它要求您在使用之前檢查類型。如果未知,TypeScript 將強制您在使用變數之前確認變數是某種類型。
let value: any = "Hello, world!";
let stringLength = (value as string).length;
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
  1. 定義特定類型:嘗試為每個變數定義確切的類型。例如,如果您知道 value 將始終是字串,請使用 string 而不是 any。
let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
  1. 對複雜數據使用介面:對於物件或複雜數據,建立一個描述結構的介面。這樣,TypeScript 可以檢查每個屬性並確保您的資料符合您的預期。
   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
  1. 只使用any作為最後的手段:如果您絕對必須使用any,請嘗試將其限制在程式碼的一小部分,並添加註解來解釋為什麼它是必要的。

避免使用任何未知或特定類型,您可以讓程式碼更安全並降低意外錯誤的風險,從而使您的 TypeScript 程式碼更強大、更可靠。

錯誤#3:混淆任何和未知

任何和未知有什麼區別?

在 TypeScript 中,當您不確定變數的確切類型時,可以使用 any 和unknown 類型。但有一個重要的區別:

  • any:允許您對變數執行任何操作,而無需進行任何類型檢查。它本質上關閉了 TypeScript 的安全功能。
  • 未知:要求您在以特定方式使用變數之前檢查類型。這是一個更安全的選擇,因為在驗證其類型之前,TypeScript 會阻止您以無意義的方式使用它。

為什麼未知往往更安全

使用unknown通常比任何方法都安全,因為它強制您在使用變數之前檢查類型。這有助於防止當您不確定正在使用的類型時可能發生的錯誤。

例如,假設您正在使用一個變量,但您不知道它是字串還是數字:

let value: any = "Hello!";
value = 42; // No problem, even though it started as a string.
登入後複製
登入後複製
登入後複製
登入後複製

這裡,由於 value 未知,TypeScript 不會讓你使用 value.toUpperCase() ,直到你確認它是一個字串。如果您嘗試在不進行類型檢查的情況下使用 toUpperCase(),TypeScript 將顯示錯誤,有助於防止執行時間錯誤。

另一方面,對於任何:

let value: any = "Hello!";
console.log(value.toUpperCase()); // This is fine
value = 42;
console.log(value.toUpperCase()); // TypeScript won’t catch this, but it will cause an error at runtime
登入後複製
登入後複製
登入後複製

如果 value 後來變成了數字,這段程式碼在運行時會拋出一個錯誤,並且 TypeScript 不會警告你。使用unknown有助於避免此問題,因為首先需要進行類型檢查。

如何在任意和未知之間進行選擇

  1. 當類型不確定時使用unknown:如果您不知道變數的類型並且需要在使用它之前執行檢查,請使用unknown。它更安全,因為 TypeScript 會確保您在執行任何特定操作之前檢查類型。

  2. 盡可能避免任何:any 應該是最後的手段,因為它刪除了 TypeScript 的類型檢查。只有當您確定根本不需要檢查類型時才使用 any,而且這確實無關緊要。

  3. 添加未知的類型檢查:每當您使用未知時,請記住在使用它之前添加檢查。這可以保持 TypeScript 的安全功能處於活動狀態,並有助於防止意外錯誤。

  4. 首選特定類型:如果您知道該類型是什麼,請使用該類型而不是任何類型或未知類型。這使您的程式碼更可預測且更易於理解。

使用unknown可以讓你的程式碼更安全,並防止可能漏掉的錯誤。它鼓勵良好的習慣,例如始終了解您正在使用的資料類型,以便您可以編寫更可靠的 TypeScript 程式碼。

錯誤 #4:忽略 Null 和未定義的值

理解 TypeScript 中的 Null 和 Undefined

在 TypeScript 中,nullundefined 表示「空」或「未設定」的值。

  • null 用於故意沒有值的情況,例如故意將表單中的欄位留空。
  • 未定義表示尚未分配值,就像建立變數但未賦予值時一樣。

如果忽略這些「空」值,當您嘗試使用可能為 null 或未定義的變數時,可能會導致錯誤。

Null 和未定義的常見錯誤

當 TypeScript 不考慮 null 或 undefined 時,您可能會嘗試使用變量,就好像它有值一樣,卻發現它沒有值。這可能會導致運行時錯誤(程式碼運行時發生的錯誤)。

例如:

let value: any = "Hello, world!";
let stringLength = (value as string).length;
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

這裡,user 為 null,因此嘗試存取 user.name 會拋出錯誤。如果您不處理值可能為 null 或未定義的情況,您的程式碼可能會意外中斷。

如何避免這個錯誤

  1. 使用選用連結 (?.):選用連結是 TypeScript 中的功能,可協助您安全地存取屬性,即使物件可能為 null 或未定義。使用 ?.,TypeScript 將在嘗試存取屬性之前檢查該物件是否存在。如果沒有,它只會回傳 undefined 而不是拋出錯誤。
let value: any = "Hello, world!";
let stringLength = (value as string).length;
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
  1. 非空斷言 (!):有時您確定程式碼中某點的值不為 null 或未定義,但 TypeScript 不確定。您可以使用非空斷言 (!) 告訴TypeScript,「我知道這個值不為null 或未定義。」但是,請小心使用它,因為如果該值確實為空,您仍然會收到錯誤。
let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
  1. 啟用嚴格空檢查:TypeScript 的 strictNullChecks 設定有助於確保處理空白和未定義的情況。啟用此選項後,TypeScript 不會讓您使用可能為 null 或未定義的變數而不先檢查它們,這有助於及早捕獲錯誤。

要開啟嚴格的 null 檢查,您可以將 "strictNullChecks": true 加入到 tsconfig.json 檔案中。這樣,TypeScript 將要求您正確處理 null 和 undefined,從而使您的程式碼更安全。

正確處理空值和未定義值可以幫助您避免錯誤,並防止程式碼在遇到空值時崩潰。使用可選連結、非空斷言和嚴格的空檢查可以使您的 TypeScript 程式碼更可靠、更易於使用。

錯誤 #5:類型註解的錯誤使用

什麼是類型註解?

類型註解是指告訴 TypeScript 變數、函數或參數應該具有哪種型別。例如,如果您知道變數始終是數字,則可以編寫:

   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

這清楚地表明年齡是一個數字。如果您嘗試將年齡用作其他類型(例如字串),TypeScript 會使用此資訊來擷取錯誤。

類型註釋的常見錯誤

有時,人們會在類型註解上犯錯,例如:

  1. 分配錯誤的類型:例如,說某個東西是字串,但實際上它是數字。這可能會導致錯誤和混亂。
let value: any = "Hello, world!";
let stringLength = (value as string).length;
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
  1. 過度註解:這是當你在任何地方添加類型註解時,即使 TypeScript 已經知道類型。在許多情況下,TypeScript 足夠智能,可以自行確定類型,因此並不總是需要額外的註釋。添加太多類型註釋會使您的程式碼看起來混亂且難以閱讀。
let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

為什麼過度使用類型註解會令人困惑

當你過度使用註解時,它會讓你的程式碼看起來重複且令人困惑。 TypeScript 根據變數的值自動「推斷」(計算出)變數的類型。因此,如果 TypeScript 能夠正確猜測類型,則無需每次都寫出類型。

例如這段程式碼:

   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

TypeScript 已經理解 isComplete 是一個布林值,因此不需要加入 : boolean。

如何避免類型註釋的錯誤使用

  1. 在可能的情況下讓 TypeScript 推斷類型:如果直接為變數賦值,則可以跳過類型註解。 TypeScript 將根據值自動偵測類型。
let value: any = "Hello!";
value = 42; // No problem, even though it started as a string.
登入後複製
登入後複製
登入後複製
登入後複製
  1. 僅在需要時使用註釋:當 TypeScript 無法自行推斷類型時新增類型註釋,例如函數參數或複雜物件。
let value: any = "Hello!";
console.log(value.toUpperCase()); // This is fine
value = 42;
console.log(value.toUpperCase()); // TypeScript won’t catch this, but it will cause an error at runtime
登入後複製
登入後複製
登入後複製
  1. 檢查類型準確性:如果您確實添加了類型註釋,請確保它們是正確的。仔細檢查類型是否與所使用的實際值匹配,以避免不匹配,例如當某項實際上是數字時稱為字串。

讓 TypeScript 盡可能處理類型,並僅在必要時添加清晰的註釋,將使您的程式碼更乾淨、更易於閱讀並且不易出錯。這使您的 TypeScript 程式碼變得簡單且易於理解!

錯誤#6:忘記結構類型

什麼是結構類型?

TypeScript 使用稱為結構類型的東西。這意味著 TypeScript 關心物件的形狀或結構來決定它是否與某種類型相容,而不是專注於該類型的名稱。

換句話說,如果兩個物件具有相同的屬性和類型,TypeScript 會認為它們相同 - 即使它們具有不同的名稱。

例如:

   let value: unknown = "Hello!";
   if (typeof value === "string") {
       console.log(value.toUpperCase());
   }
登入後複製
登入後複製

這裡,座標和另一個座標具有相同的結構,因此 TypeScript 認為它們是相容的。 TypeScript 不關心另一個座標是否稱為 Point;它只會檢查它是否具有數字類型的 x 和 y 屬性。

結構類型的常見錯誤

一個常見的錯誤是假設 TypeScript 使用名目類型(基於名稱的類型)。在名義類型中,兩個事物必須在名稱上具有完全相同的類型才能相容。但在 TypeScript 的結構系統中,如果形狀匹配,TypeScript 會將它們視為相同類型。

例如,開發人員可能認為只有 Point 類型的物件才能指派給座標。但是,TypeScript 允許任何具有相同結構的對象,無論其類型名稱為何。如果您不熟悉結構類型,這可能會令人困惑,因為它允許來自程式碼不同部分的具有匹配形狀的物件被視為相同類型。

如何避免結構類型錯誤

  1. 了解基於形狀的方法:請記住,TypeScript 更關心結構(屬性和類型)而不是名稱。專注於物件具有的屬性,而不是其類型名稱。

  2. 小心額外屬性:如果向物件新增額外屬性,在某些情況下它可能仍然與預期類型相符。為了避免混淆,請確保物件僅具有給定類型所需的屬性。

  3. 使用介面和類型別名來強制結構:儘管TypeScript 在結構類型方面很靈活,但創建介面類型別名 可以幫助定義清晰的結構並向其他開發人員傳達預期的形狀。這種做法可以讓你的程式碼更容易理解。

let value: any = "Hello, world!";
let stringLength = (value as string).length;
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
  1. 在需要時依賴類型檢查:TypeScript 的結構類型在靈活性方面非常強大,但了解具有匹配結構的物件如何交互仍然很重要。如果您想更嚴格,您可以使用類別或技術來確保每種類型都是唯一的。

TypeScript 的結構類型系統提供了靈活性,但了解它的工作原理很重要,以避免意外。透過專注於類型的形狀並使用介面或類型別名,您可以充分利用系統,同時保持程式碼清晰可靠。

錯誤#7:錯誤定義物件形狀

為什麼定義物件形狀很重要

在 TypeScript 中,當你建立一個物件時,你應該定義它有哪些屬性以及每個屬性應該是什麼類型。這稱為定義物件的形狀。當形狀定義不正確時,可能會導致執行階段錯誤-執行程式碼時發生的錯誤。

例如,如果您說一個物件應該有名稱和年齡,但您忘記添加年齡,TypeScript 可能會在某些情況下讓它滑動,但稍後當您嘗試使用年齡時,您的程式碼可能會崩潰。

現實世界的例子

假設您正在定義一個應具有名稱和年齡的 User 物件:

let value: any = "Hello, world!";
let stringLength = (value as string).length;
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

現在,如果您建立一個使用者但忘記添加年齡,您可能會遇到麻煩:

let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

這是一個簡單的錯誤,但如果您期望年齡始終存在,則可能會導致問題。如果您沒有正確定義物件形狀,您可能會意外地跳過重要屬性,從而在嘗試存取這些屬性時導致錯誤。

如何避免這個錯誤

  1. 使用介面和型別別名:在 TypeScript 中使用 介面型別別名 清楚定義物件的結構。這可以確保每當您建立物件時所有必填欄位都已就位。
   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
  1. 需要時使用可選屬性:如果某個屬性並不總是必需的,您可以使用 ? 將其標記為可選。這樣,如果您省略它,TypeScript 不會抱怨,但它仍然會檢查其他必填欄位。
let value: any = "Hello!";
value = 42; // No problem, even though it started as a string.
登入後複製
登入後複製
登入後複製
登入後複製
  1. 利用實用程式類型:TypeScript 具有內建實用程式類型,例如 Partial 來協助實現靈活的形狀。例如,如果您僅更新物件的一部分,則可以使用 Partial允許省略屬性。
let value: any = "Hello!";
console.log(value.toUpperCase()); // This is fine
value = 42;
console.log(value.toUpperCase()); // TypeScript won’t catch this, but it will cause an error at runtime
登入後複製
登入後複製
登入後複製
  1. 仔細檢查所需的屬性:在定義或使用物件時,請務必檢查物件是否具有所有必要的欄位。缺少必需的屬性可能會導致問題,因此驗證您的物件是否與定義的形狀相符是一個好習慣。

透過仔細定義物件形狀,您可以確保每個物件都具有所需的字段,從而使您的程式碼更加可靠並降低錯誤風險。使用 TypeScript 的工具(例如介面、可選屬性和實用類型)可以幫助您準確定義形狀並使程式碼更易於維護。

錯誤#8:過度使用枚舉

什麼是枚舉?

在 TypeScript 中,枚舉是定義一組命名值的方法。它們允許您將相關值分組到一個名稱下。例如:

   let value: unknown = "Hello!";
   if (typeof value === "string") {
       console.log(value.toUpperCase());
   }
登入後複製
登入後複製

當您需要表示一組有限的值(例如任務的狀態)時,枚舉非常有用。但有時,過度使用枚舉會讓你的程式碼比需要的更複雜。

為什麼過度使用枚舉可能會出現問題

  1. 讓程式碼更難閱讀:使用枚舉時,您需要記住枚舉值的名稱,這會增加不必要的複雜性。例如:
   let value: string = "Hello!";
登入後複製

雖然這看起來不錯,但如果您到處使用枚舉,您的程式碼可能會變得更難快速理解,特別是對於不熟悉枚舉定義的開發人員。

  1. 增加程式碼維護:當您在程式碼中使用枚舉時,日後更新或變更值可能會更具挑戰性。您可能需要在許多地方搜尋和更新枚舉,從而導致額外的工作。

  2. 不必要的抽象:有時,枚舉會添加不必要的抽象層級。例如,簡單的字串或數字也可以完成這項工作,而不需要列舉。

如何避免過度使用枚舉

  1. 使用聯合類型:如果您只需要一小組值,請考慮使用聯合類型而不是枚舉。聯合類型更簡單且更易於維護。
let value: any = "Hello, world!";
let stringLength = (value as string).length;
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

在這裡,Status 只是一組可能的值。它比枚舉更簡單,並且仍然提供類型安全。

  1. 在簡單情況下使用字串文字:如果您的值是簡單字串,則只需使用字串文字而不是枚舉。例如:
let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

這使事情變得簡單明了,無需創建整個枚舉。

  1. 在特定情況下堅持使用枚舉:當您需要表示更複雜的東西時,例如向枚舉添加方法或當值需要更具描述性時,枚舉非常有用。例如,如果您正在使用一組需要附加功能的狀態代碼,則枚舉可能有意義。但對於簡單的值集​​,最好避免使用它們。

何時使用枚舉

枚舉非常適合以下情況:

  • 您需要一個相關值的命名集合,這些值將在程式碼中的許多地方使用。
  • 您需要更多與值相關的功能(例如方法或計算屬性)。

但是對於簡單的值集​​,使用聯合類型或字串文字通常是更好、更簡單的解決方案。

透過避免過度使用枚舉,您的程式碼將變得更易於閱讀、維護和理解,使其更乾淨、更有效率。

錯誤#9:誤解泛型

什麼是泛型?

TypeScript 中的泛型是一種建立可用於任何類型的可重複使用程式碼的方法,同時仍保持型別安全。它們允許您編寫可以使用不同類型的函數、類別或接口,而不會失去 TypeScript 類型檢查的優勢。

例如:

   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

在本例中,T 是類型的佔位符,該類型將在呼叫函數時確定。您可以傳遞任何類型(如字串、數字等),TypeScript 將確保類型匹配。

泛型的常見錯誤

  1. 不正確的類型約束:有時,開發人員嘗試為泛型添加約束,但會出錯。例如,您可能嘗試使用限制性太大或對您正在使用的函數或類別沒有意義的約束。
let value: any = "Hello, world!";
let stringLength = (value as string).length;
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

這裡,T 被限制為一個字串,這對於 length 屬性來說是有意義的。但如果您使用了不必要或不正確的約束,該函數可能會因其他類型而中斷。

  1. 使程式碼過於複雜:錯誤或不必要地使用泛型可能會使您的程式碼比需要的更複雜。例如,您可以建立一個泛型類型或函數,其中更簡單的解決方案也可以正常運作。
let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

此函數不需要是通用的,因為您只需組合任意類型的兩個值。您可以在不使用泛型的情況下簡化它。

如何避免對泛型的誤解

  1. 僅在必要時使用泛型:您並不總是需要泛型。如果程式碼不需要使用不同的類型,最好只使用特定的類型。泛型很強大,但只有在它們增加價值時才應該使用。

  2. 了解類型約束:當您使用泛型時,請確保約束有意義。只限制需要限制的類型。例如,如果您正在使用數組,請使用 T[] 或 Array作為約束。

   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
  1. 盡可能簡化:不要使用不必要的泛型使程式碼過於複雜。如果簡單類型(如字串或數字)工作正常,請不要嘗試用泛型來概括它。當您想要讓函數或類別靈活地適應不同類型時,請使用泛型。

  2. 使用預設泛型:如果您想要讓泛型更容易使用,您可以指定一個預設類型,以防使用者不提供預設類型。

let value: any = "Hello!";
value = 42; // No problem, even though it started as a string.
登入後複製
登入後複製
登入後複製
登入後複製

這裡,如果使用者沒有指定類型,T 將預設為字串。

重點

  • 泛型非常適合可重複使用、靈活的程式碼,但如果使用不當,它們可能會造成混亂。
  • 注意類型約束-不要過多或不正確地限制類型。
  • 僅當泛型為程式碼增加價值時才使用泛型。簡單的類型通常就足夠了。

透過了解泛型如何運作以及何時使用它們,您可以避免常見錯誤,並使您的程式碼更加靈活、可讀和可維護。

錯誤 #10:忽略 TypeScript 設定選項

什麼是 TypeScript 配置選項?

TypeScript 有一個設定檔,名稱為 tsconfig.json,您可以在其中設定各種選項來自訂 TypeScript 編譯程式碼的方式。此配置允許您執行更嚴格的規則並在潛在錯誤導致程式碼出現問題之前更早地捕獲它們。

為什麼忽略配置可能會出現問題

如果您不注意 TypeScript 配置,它可能無法捕獲某些可能導致程式碼錯誤或問題的錯誤或問題。例如,如果啟用了正確的設置,TypeScript 可能允許您編寫通常會被標記為不正確的程式碼。

忽略這些設置,您可能會錯過重要警告並降低程式碼的安全性。

需要注意的關鍵 TypeScript 設定選項

  1. 嚴格:這是一個特殊的設置,可以同時打開幾個重要的嚴格檢查。它有助於確保您的程式碼類型安全,並且不依賴任何類型的鬆散或弱類型。

為什麼它很重要:啟用 strict 時,TypeScript 會檢查未初始化的變數、空檢查等。這可以幫助您及早發現潛在問題。

let value: any = "Hello, world!";
let stringLength = (value as string).length;
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
  1. noImplicitAny:此設定阻止 TypeScript 允許將變數、參數或傳回值鍵入為 any,除非明確宣告。 any 允許分配任何值,這會繞過 TypeScript 的類型檢查系統。

為什麼它很重要:使用 noImplicitAny,TypeScript 會強制你指定一個類型,防止你意外使用任何類型檢查會捕獲的潛在錯誤。

let value: any = 42;
let stringLength = (value as string).length; // This will throw an error at runtime
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
  1. strictNullChecks:啟用後,此設定可確保除非明確指定,否則 null 和 undefined 不會被視為任何類型的有效值。它有助於防止因意外嘗試使用 null 或未定義而可能出現的錯誤。

為什麼它很重要:如果沒有此設置,TypeScript 將允許將 null 和 undefined 分配給任何變量,這可能會導致運行時錯誤。

   let value: any = 42;
   if (typeof value === 'string') {
       let stringLength = (value as string).length;
   }
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

如何避免這個錯誤

  1. 啟用嚴格模式:在 tsconfig.json 中始終啟用嚴格標誌。這將自動開啟幾個有用的設置,包括 noImplicitAny 和 strictNullChecks。這是確保您的程式碼盡可能安全且無錯誤的最佳方法之一。

  2. 查看和自訂設定:花點時間查看 TypeScript 編譯器選項的完整清單。自訂它們以滿足您的專案的需求。您可以啟用或停用某些檢查,以使您的程式碼更加可靠和可維護。

  3. 總是啟用 noImplicitAny:除非絕對必要,否則避免使用 any 類型。透過啟用 noImplicitAny,您將被迫考慮變數的類型,這將使您的程式碼更安全。

  4. 使用 strictNullChecks 捕獲 Null 錯誤:如果處理不仔細,Null 值很容易導致錯誤。透過啟用 strictNullChecks,您可以確保 null 或 undefined 不會陷入可能導致問題的地方。

重點

  • TypeScript 的編譯器選項是強大的工具,可以幫助您在錯誤發生之前捕獲它們。
  • 始終啟用嚴格模式以確保您充分利用 TypeScript 的類型系統。
  • 使用 noImplicitAnystrictNullChecks 選項來捕捉與無類型變數和空值相關的錯誤。

透過正確配置 TypeScript 的設置,您可以避免常見的陷阱,並使您的程式碼更可靠、更易於維護且不易出現錯誤。

結論

TypeScript 是一個強大的工具,可以幫助開發人員編寫更安全、更可靠的程式碼,但剛開始時很容易犯錯。我們已經介紹了最常見的 TypeScript 陷阱,例如誤用類型斷言、過度使用 any、忽略可為空性以及誤解泛型。這些錯誤可能會導致意外的錯誤和難以維護的程式碼。

這裡有一個快速清單,可以避免這些錯誤:

  • 不要濫用類型斷言:只有在確定類型時才使用它們。
  • 避免使用太多:嘗試使用未知或更具體的類型。
  • 理解any和unknown之間的差異:unknown更安全,並迫使你在使用它們之前檢查類型。
  • 正確處理 null 和未定義:使用可選鏈、非 null 斷言,並啟用嚴格的 null 檢查。
  • 不要過度使用枚舉:盡可能使用聯合型別或字串文字。
  • 正確使用泛型:不要使事情過於複雜,並了解如何以正確的方式應用它們。
  • 正確配置 TypeScript:啟用嚴格設定以儘早發現問題。

透過了解這些常見錯誤並遵循本文中概述的最佳實踐,您將能夠編寫更清晰、更安全且更易於維護的 TypeScript 程式碼。

擁抱 TypeScript 的功能,讓它幫助您編寫更可靠、錯誤更少的應用程式。繼續學習,祝編碼愉快!

以上是TypeScript 陷阱:開發人員常犯的錯誤以及如何避免它們的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板