[TypeScript] 快速上手 satisfies,讓你輕鬆推論型別與類型檢查

更新 發佈閱讀 7 分鐘
TypeScript - satisfies

TypeScript - satisfies


想必大家在開發 TypeScript 的過程中,多少都會遇到一個情況:如果有一個 interface 其中之一的屬性是聯集型別,例如 string | number。如果將該 interface 指定給一個物件,且要使用到該屬性時,就會發現只能使用 stringnumber 都共有的屬性。

為了解決這個問題,在 TypeScript 4.9 版的更新中,便引入了 satisfies 來解決型別推導不精確的問題。但既然有了斷言和 Type Guard,又為何需要 satisfies 來解決問題呢?

接下來,就讓我們來看看 satisfies 究竟解決什麼問題,又該如何使用吧!




什麼時候需要用到 satisfies

satisfies 是為了解決在聯合型別或擴展型別的情況下,在不修改變數所屬型別的情況下,靜態推導型別的問題。

satisfies 的使用場景主要集中在以下兩個方面:

  • 不修改原有型別的情況下,確保資料符合特定型別。
  • 進行更細部的靜態型別推導,同時避免引入執行時的負擔。


satisfies 的使用方式

satisfies 的使用方式,其實主要的目的和 interfacetype 的效果接近。

interface Obj1 {
a: number;
b: string;
}

const obj1 = {
a: 1,
b: 2, // Type "number" is not assignable to type "string".
} satisfies Obj1;

接下來,就讓我們透過實際案例,來進一步了解 satisfies 吧!




一、為聯集屬性推定型別

假設有兩種 Task 的形式,一種是 DetailedTask,另一種則是 SimpleTask。當我們生成一個新的 User 物件時,task 的屬性有可能是一個物件或 string。但 TypeScript 沒辦法確認資料有可能是物件還是 string,因此在使用 string 專屬的 charAt 方法時就會報錯。

type SimpleTask = string;

interface DetailedTask {
description: string;
dueDate: Date;
}

type Task = SimpleTask | DetailedTask;

interface User {
name: string;
task: Task;
}

const badUser: User = {
name: "John",
task: "Finish report"
}

badUser.task.charAt() // charAt 會報錯


方案一:透過斷言 as 指定型別

直接透過 as 斷言來確認 badUser 的型別,但帶來的缺點也顯而易見。除了程式碼的易讀性會變低,也會讓程式碼脫離 TypeScript 的型別檢查。因為 as 的目的就是告訴編譯器,不要管我在做什麼,我告訴你這是什麼。

(badUser.task as SimpleTask).charAt(0); // OK


方案二:透過型別謂詞縮減型別

透過型別謂詞來確定型別。透過判別是否為 SimpleTask,讓 TS 知道如何辨別所屬的物件,進而提供可選用的方法。若想進一步了解型別謂詞,可參考 10 分鐘學會 TS 中必會的 5 種型別防禦 Type Guard

function isSimpleTask(task: Task): task is SimpleTask {
return typeof task === "string";
}

if (isSimpleTask(badUser.task)) {
badUser.task.charAt(0); // ok
}


方案三:透過 satisfies 自動推導型別

最後,便是使用 satisfies 來自動推導型別。相較於上面兩個方法,satisfies 能夠自動推導出 badUser.task 屬於 string 型別,因此能夠自動提供 charAt() 的方法。

const goodUser = {
name: "Cat",
task: "Finish the report",
} satisfies User;

goodUser.task.charAt(); // ok

與此同時,當我們滑到 goodUser.task 上時,可以看到編譯器已經幫我們推導出 string 的型別,讓我們能夠自然而然的使用 string 的方法 trim

satisfies type inference

satisfies type inference




二、動態推定擴展型別的資料型別

除了聯集型別可以推定,也可以推定擴展型別,如 [key: string]: any;

TypeScript 僅會提示顯式聲明型別的屬性,但屬於擴展型別範圍的則不會顯示。例如顯式指定了 ab 兩個屬性。

type Obj = {
a: number,
b: string,
[key: string]: any,
}

const objType: Obj = {
a: 1,
b: 2, // 顯示型別錯誤
c: 3, // 不會自動推導
}
raw-image



因為 c 並沒有在 Obj1 中被指定,則在選則 c 屬性時,編譯器並不會有任何提示。可以發現下面的自動補齊完全沒有出現 c



使用 satisfies 後的差異

相反地,使用 satisfies 後,則可以在顯示聲明時檢查顯式聲明 ab,而自動推導 c 的型別。

type Obj = {
a: number,
b: string,
[key: string]: any,
}

const ObjSatisfies = {
a: 1,
b: 2, // 顯示型別錯誤
c: 3, // 自動推導為 number
}
raw-image


可以發現右邊的 obj1. 出現了 c 的自動補齊,代表編譯器有自動推導出 c 的屬性與型別,且 c 的屬性也被正確推導為 number,因而能夠使用 number 特有的屬性。



因此善用 satisfies,可以讓我們在動態推導型別時,能夠兼具程式碼的簡潔,同時也能維護程式碼的型別安全,並讓自動補齊能夠順利做動。


結論與延伸

透過這些例子,我們其實可以發現 TypeScript 其實擁有多種方式可以提升型別安全,但在個別的情境下,又有各自合適的案例。因此當我們需要為一個 typeinterface 檢驗其屬性的型別,屬於聯集型別的哪一種時,就可以使用 satisfies 來達成目的。

如果有任何的筆誤或想法,都歡迎你留言一起討論,讓我們一起深入探索 TypeScript 的強大功能吧!


參考資料 Reference

留言
avatar-img
留言分享你的想法!
avatar-img
學.誌|Chris Kang的沙龍
7.5K會員
14內容數
此處作為整理前端(Frontend)和相關的 HTML、CSS、JavaScript、React 等前端觀念與技巧,全部都會收錄在這個專題之中。同時也會將相關的技術與反思記錄在此,歡迎各位讀者互相交流。
2024/03/26
本文介紹 TypeScript 常遇到的混合型別,以及如何透過五種型別防禦(Type Guard)來解決。涵蓋了使用型別斷言、型別謂詞、in 運算子、typeof 運算子以及 instanceof 運算子這幾種方式。透過本文的學習,能夠更好地運用 TypeScript 進行程式碼開發。
Thumbnail
2024/03/26
本文介紹 TypeScript 常遇到的混合型別,以及如何透過五種型別防禦(Type Guard)來解決。涵蓋了使用型別斷言、型別謂詞、in 運算子、typeof 運算子以及 instanceof 運算子這幾種方式。透過本文的學習,能夠更好地運用 TypeScript 進行程式碼開發。
Thumbnail
2024/02/04
本文將深入探討鏈表的核心概念,使用 JavaScript 來說明如何實現和操作鏈表(Linked List),包括 append、prepend、remove、find 和 reverse 等五大方法。
Thumbnail
2024/02/04
本文將深入探討鏈表的核心概念,使用 JavaScript 來說明如何實現和操作鏈表(Linked List),包括 append、prepend、remove、find 和 reverse 等五大方法。
Thumbnail
2023/08/08
「px」,即像素,是最基本的單位,它常被用於指定字體大小、邊框粗細等。「em」和「rem」通常用於調整相對大小,「em」在子元素中的適用,而「rem」則以根元素為參考。另一方面,「vh」和「vw」分別代表視窗的高度和寬度百分比,特別適合實現響應式設計。「vmin」和「vmax」則根據視窗的最小或最大
Thumbnail
2023/08/08
「px」,即像素,是最基本的單位,它常被用於指定字體大小、邊框粗細等。「em」和「rem」通常用於調整相對大小,「em」在子元素中的適用,而「rem」則以根元素為參考。另一方面,「vh」和「vw」分別代表視窗的高度和寬度百分比,特別適合實現響應式設計。「vmin」和「vmax」則根據視窗的最小或最大
Thumbnail
看更多
你可能也想看
Thumbnail
嶄新的台灣獨立調香師品牌Sunkronizo ,這個名稱源自希臘語「同步」的意思。讓香氛不單純只是氣味調製,更是個人風格的展現與靈魂意志延伸的一種溝通語言。 很適合接下來年底聖誕佳節送禮的試香組,以一星期中的日子來為全系列香氛產品命名, 是品牌創立後首個推出全系列概念作品...
Thumbnail
嶄新的台灣獨立調香師品牌Sunkronizo ,這個名稱源自希臘語「同步」的意思。讓香氛不單純只是氣味調製,更是個人風格的展現與靈魂意志延伸的一種溝通語言。 很適合接下來年底聖誕佳節送禮的試香組,以一星期中的日子來為全系列香氛產品命名, 是品牌創立後首個推出全系列概念作品...
Thumbnail
根據美國電影協會(MPA)主辦的「串流服務如何推動臺灣創意經濟」論壇內容,深入探討串流平臺對臺灣影視產業的影響、數據分析、政府政策建議、內容國際化策略,以及臺灣與「韓流」的差距。文章提出 awwrated 在串流生態系中的潛在角色,強調數據、策略與自信是臺灣影視產業發展的關鍵。
Thumbnail
根據美國電影協會(MPA)主辦的「串流服務如何推動臺灣創意經濟」論壇內容,深入探討串流平臺對臺灣影視產業的影響、數據分析、政府政策建議、內容國際化策略,以及臺灣與「韓流」的差距。文章提出 awwrated 在串流生態系中的潛在角色,強調數據、策略與自信是臺灣影視產業發展的關鍵。
Thumbnail
本文探討串流平臺(VOD)如何徹底改變好萊塢和臺灣影視產業的生態。從美國電影協會(MPA)的數據報告,揭示串流服務在臺灣的驚人普及率與在地內容的消費趨勢。文章分析國際作品如何透過在地化元素開拓新市場。同時,作者也擔憂政府過度監管可能扼殺臺灣影視創新自由,以越南為鑑,呼籲以開放態度擁抱串流時代的新機遇
Thumbnail
本文探討串流平臺(VOD)如何徹底改變好萊塢和臺灣影視產業的生態。從美國電影協會(MPA)的數據報告,揭示串流服務在臺灣的驚人普及率與在地內容的消費趨勢。文章分析國際作品如何透過在地化元素開拓新市場。同時,作者也擔憂政府過度監管可能扼殺臺灣影視創新自由,以越南為鑑,呼籲以開放態度擁抱串流時代的新機遇
Thumbnail
一般在使用 TypeScript 的時候,大家都有遇過定義列舉資料的情境吧。 不過不管是 enum 和 literal 的方式其實都有些小缺點,以下推薦一個個人認為體驗更好的方式。
Thumbnail
一般在使用 TypeScript 的時候,大家都有遇過定義列舉資料的情境吧。 不過不管是 enum 和 literal 的方式其實都有些小缺點,以下推薦一個個人認為體驗更好的方式。
Thumbnail
在 TypeScript 中,套件是模組化代碼的集合,可以提高代碼的可重用性和可維護性。常見的套件包括各種庫和框架,如 lodash、express 等。以下是有關引用套件、自定義套件和常見套件的詳細介紹。
Thumbnail
在 TypeScript 中,套件是模組化代碼的集合,可以提高代碼的可重用性和可維護性。常見的套件包括各種庫和框架,如 lodash、express 等。以下是有關引用套件、自定義套件和常見套件的詳細介紹。
Thumbnail
本章節旨在介紹TypeScript中的函數,包括其基本結構、如何呼叫函數、函數的參數以及函數的返回值等相關概念。通過本章節,讀者可以學習到如何在TypeScript中使用不同的方式來定義函數,如函數聲明、函數表達式、箭頭函數和匿名函數等。
Thumbnail
本章節旨在介紹TypeScript中的函數,包括其基本結構、如何呼叫函數、函數的參數以及函數的返回值等相關概念。通過本章節,讀者可以學習到如何在TypeScript中使用不同的方式來定義函數,如函數聲明、函數表達式、箭頭函數和匿名函數等。
Thumbnail
本章節旨在介紹 TypeScript 的基本資料型別,包括內建型別、型別轉換、自訂型別、元組、集合、陣列、和字典型別。透過理解和使用這些型別,可以提高代碼的可讀性和可維護性。
Thumbnail
本章節旨在介紹 TypeScript 的基本資料型別,包括內建型別、型別轉換、自訂型別、元組、集合、陣列、和字典型別。透過理解和使用這些型別,可以提高代碼的可讀性和可維護性。
Thumbnail
本章節旨在介紹TypeScript的基本語法,包括一般結構、程式進入點、註解以及變數的定義和賦值。這些知識將幫助讀者瞭解TypeScript的基本架構,並且可以開始使用TypeScript進行開發。
Thumbnail
本章節旨在介紹TypeScript的基本語法,包括一般結構、程式進入點、註解以及變數的定義和賦值。這些知識將幫助讀者瞭解TypeScript的基本架構,並且可以開始使用TypeScript進行開發。
Thumbnail
TypeScript是一種由Microsoft開發和維護的開源編程語言。它是JavaScript的超集,主要擴展了JavaScript的語法,增加了靜態類型檢查和其他特性,使得開發大型應用程序更為方便和可靠。
Thumbnail
TypeScript是一種由Microsoft開發和維護的開源編程語言。它是JavaScript的超集,主要擴展了JavaScript的語法,增加了靜態類型檢查和其他特性,使得開發大型應用程序更為方便和可靠。
Thumbnail
針對 JavaScript 中的原始型別和隱性轉型進行了詳細的探討
Thumbnail
針對 JavaScript 中的原始型別和隱性轉型進行了詳細的探討
Thumbnail
本文帶你深入探索 TypeScript 中的 satisfies 特性,能幫助你實現精確的型別推導與型別檢查。透過實際案例,展示如何使用 satisfies 提升代碼的型別安全與程式碼的整潔,是每位 TypeScript 開發者不可或缺的知識。
Thumbnail
本文帶你深入探索 TypeScript 中的 satisfies 特性,能幫助你實現精確的型別推導與型別檢查。透過實際案例,展示如何使用 satisfies 提升代碼的型別安全與程式碼的整潔,是每位 TypeScript 開發者不可或缺的知識。
Thumbnail
本文介紹 TypeScript 常遇到的混合型別,以及如何透過五種型別防禦(Type Guard)來解決。涵蓋了使用型別斷言、型別謂詞、in 運算子、typeof 運算子以及 instanceof 運算子這幾種方式。透過本文的學習,能夠更好地運用 TypeScript 進行程式碼開發。
Thumbnail
本文介紹 TypeScript 常遇到的混合型別,以及如何透過五種型別防禦(Type Guard)來解決。涵蓋了使用型別斷言、型別謂詞、in 運算子、typeof 運算子以及 instanceof 運算子這幾種方式。透過本文的學習,能夠更好地運用 TypeScript 進行程式碼開發。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News