[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
透過蝦皮分潤計畫,輕鬆賺取零用金!本文分享5-6月實測心得,包含數據流程、實際收入、平臺優點及注意事項,並推薦高分潤商品,教你如何運用空閒時間創造被動收入。
Thumbnail
透過蝦皮分潤計畫,輕鬆賺取零用金!本文分享5-6月實測心得,包含數據流程、實際收入、平臺優點及注意事項,並推薦高分潤商品,教你如何運用空閒時間創造被動收入。
Thumbnail
單身的人有些會養寵物,而我養植物。畢竟寵物離世會傷心,植物沒養好再接再厲就好了~(笑)
Thumbnail
單身的人有些會養寵物,而我養植物。畢竟寵物離世會傷心,植物沒養好再接再厲就好了~(笑)
Thumbnail
不知你有沒有過這種經驗?衛生紙只剩最後一包、洗衣精倒不出來,或電池突然沒電。這次一次補貨,從電池、衛生紙到洗衣精,還順便分享使用心得。更棒的是,搭配蝦皮分潤計畫,愛用品不僅自己用得安心,分享給朋友還能賺回饋。立即使用推薦碼 X5Q344E,輕鬆上手,隨時隨地賺取分潤!
Thumbnail
不知你有沒有過這種經驗?衛生紙只剩最後一包、洗衣精倒不出來,或電池突然沒電。這次一次補貨,從電池、衛生紙到洗衣精,還順便分享使用心得。更棒的是,搭配蝦皮分潤計畫,愛用品不僅自己用得安心,分享給朋友還能賺回饋。立即使用推薦碼 X5Q344E,輕鬆上手,隨時隨地賺取分潤!
Thumbnail
身為一個典型的社畜,上班時間被會議、進度、KPI 塞得滿滿,下班後只想要找一個能夠安靜喘口氣的小角落。對我來說,畫畫就是那個屬於自己的小樹洞。無論是胡亂塗鴉,還是慢慢描繪喜歡的插畫人物,那個專注在筆觸和色彩的過程,就像在幫心靈按摩一樣,讓緊繃的神經慢慢鬆開。
Thumbnail
身為一個典型的社畜,上班時間被會議、進度、KPI 塞得滿滿,下班後只想要找一個能夠安靜喘口氣的小角落。對我來說,畫畫就是那個屬於自己的小樹洞。無論是胡亂塗鴉,還是慢慢描繪喜歡的插畫人物,那個專注在筆觸和色彩的過程,就像在幫心靈按摩一樣,讓緊繃的神經慢慢鬆開。
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 開發者不可或缺的知識。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News