每位開發者必須知道的20個 TypeScript 技巧 ??

TypeScript 是現代 JavaScript 開發中不可或缺的工具,它提供了類型安全和豐富的特性。許多開發者掌握了基本用法,但還有一些鮮為人知的技巧可以讓你的代碼更高效、干凈且易于維護。接下來,讓我們深入探討每位開發者應該了解的20個 TypeScript 技巧,附帶示例和實用建議!

  1. 非空類型 (NonNullable)

    NonNullable 工具類型可以消除類型中的 nullundefined,幫助你避免空值問題。

    type User = { name: string; age?: number | null };
    const user: NonNullable<User["age"]> = 30; // 不允許 null 或 undefined
    
  2. 使用 Partial 增強靈活性

    Partial<T> 將類型中的所有屬性設為可選,非常適合更新對象字段的子集。

    interface User {
      name: string;
      age: number;
      email: string;
    }
    
    const updateUser = (user: Partial<User>) => {
      return { ...user, updatedAt: new Date() };
    };
    
    updateUser({ name: 'John' }); // 不需提供完整對象
    
  3. 利用 Readonly 實現不可變數據

    Readonly<T> 將類型的所有屬性設為只讀,防止修改。

    const config: Readonly<{ apiUrl: string; retries: number }> = {
      apiUrl: 'https://api.example.com',
      retries: 5
    };
    
    // config.apiUrl = 'https://newapi.com'; // 錯誤:只讀屬性
    
  4. 映射類型實現動態屬性類型

    映射類型允許通過轉換已有類型創建新類型,非常適合創建對象類型變體。

    type Status = 'loading' | 'success' | 'error';
    type ApiResponse<T> = {
      [K in Status]: T;
    };
    
    const response: ApiResponse<string> = {
      loading: '加載中...',
      success: '數據加載成功',
      error: '出現錯誤'
    };
    
  5. 帶可選元素的元組類型

    TypeScript 支持在元組中使用可選元素,適合處理變參函數。

    type UserTuple = [string, number?, boolean?];
    
    const user1: UserTuple = ['Alice']; // 僅名字
    const user2: UserTuple = ['Bob', 30]; // 名字和年齡
    const user3: UserTuple = ['Charlie', 25, true]; // 完整元組
    
  6. 使用聯合類型進行全面檢查

    switch 語句中確保處理所有聯合類型情況,以避免遺漏。

    type Status = 'open' | 'closed' | 'pending';
    
    function handleStatus(status: Status) {
      switch (status) {
        case 'open':
          return '已打開';
        case 'closed':
          return '已關閉';
        case 'pending':
          return '待處理';
        default:
          const exhaustiveCheck: never = status; // 未處理的狀態類型會報錯
          return exhaustiveCheck;
      }
    }
    
  7. 使用 Omit 排除鍵

    使用 Omit 創建一個排除特定鍵的對象類型,方便管理。

    interface Todo {
      title: string;
      description: string;
      completed: boolean;
    }
    
    type TodoPreview = Omit<Todo, 'description'>;
    
    const todo: TodoPreview = {
      title: '學習 TypeScript',
      completed: false
    };
    
  8. 使用 ininstanceof 進行類型細化

    利用 ininstanceof 在運行時細化類型,確保代碼安全。

    function processInput(input: string | number | { title: string }) {
      if (typeof input === 'string') {
        return input.toUpperCase(); // 細化為字符串
      } else if (typeof input === 'number') {
        return input * 2; // 細化為數字
      } else if ('title' in input) {
        return input.title; // 細化為對象
      }
    }
    
  9. 使用條件類型實現高級類型邏輯

    條件類型提供了靈活的類型轉換。

    type IsString<T> = T extends string ? true : false;
    
    type CheckString = IsString<'Hello'>; // true
    type CheckNumber = IsString<42>; // false
    
  10. 使用 as const 凍結字面量類型

    as const 可以確保值被視為字面量類型,避免可變性。

    const COLORS = ['red', 'green', 'blue'] as const;
    
    type Color = typeof COLORS[number]; // 'red' | 'green' | 'blue'
    
  11. 使用 ExtractExclude 精煉類型

    通過 ExtractExclude 從聯合類型中選擇或過濾類型。

    type T = 'a' | 'b' | 'c';
    type OnlyAOrB = Extract<T, 'a' | 'b'>; // 'a' | 'b'
    type ExcludeC = Exclude<T, 'c'>; // 'a' | 'b'
    
  12. 自定義類型保護

    創建類型保護函數以動態精確化類型。

    function isString(input: any): input is string {
      return typeof input === 'string';
    }
    
    const value: any = 'Hello';
    
    if (isString(value)) {
      console.log(value.toUpperCase()); // 安全:value 是字符串
    }
    
  13. 使用 Record 創建動態對象類型

    Record<K, V> 適合創建具有動態鍵的對象類型。

    type Role = 'admin' | 'user' | 'guest';
    const permissions: Record<Role, string[]> = {
      admin: ['read', 'write', 'delete'],
      user: ['read', 'write'],
      guest: ['read']
    };
    
  14. 動態類屬性與索引簽名

    索引簽名可以讓你創建具有動態屬性名的對象或類。

    class DynamicObject {
      [key: string]: any;
    }
    
    const obj = new DynamicObject();
    obj.name = 'Alice';
    obj.age = 30;
    
  15. 使用 never 類型表示不可能的狀態

    never 類型表示不應出現的值,通常用于全面檢查。

    function assertNever(value: never): never {
      throw new Error(`意外的值: ${value}`);
    }
    
  16. 可選鏈用于安全屬性訪問

    可選鏈(?.)可以安全訪問深層嵌套的屬性。

    const user = { profile: { name: 'John' } };
    const userName = user?.profile?.name; // 'John'
    const age = user?.profile?.age ?? '未提供'; // 默認值
    
  17. 空值合并運算符(??

    使用空值合并運算符提供默認值,僅在值為 nullundefined 時生效。

    const input: string | null = null;
    const defaultValue = input ?? '默認值'; // '默認值'
    
  18. 使用 ReturnType 推斷返回類型

    ReturnType<T> 可以提取函數的返回類型,處理復雜類型時十分有用。

    function getUser() {
      return { name: 'John', age: 30 };
    }
    
    type UserReturn = ReturnType<typeof getUser>; // { name: string; age: number; }
    
  19. 函數中的類型參數

    泛型類型參數使函數在不同類型間更靈活。

    function identity<T>(value: T): T {
      return value;
    }
    
    identity<string>('Hello'); // 'Hello'
    identity<number>(42); // 42
    
  20. 交叉類型用于合并結構

    交叉類型允許將多個類型合并為一個。

    type Admin = { privileges: string[] };
    type User = { name: string };
    
    type AdminUser = Admin & User;
    
    const adminUser: AdminUser = {
      privileges: ['admin', 'editor'],
      name: 'Alice'
    };
    

這些技巧將幫助你將 TypeScript 技能提升到新層次!?? 嘗試將這些模式融入到你的項目中,以獲得更清晰、高效的代碼。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容