TS - Partial 用法及解析
FakeStandard
Posted on November 23, 2024
Typescript 的 Utility Types 有很多,Partial 就是其中之一
Partial 的描述官方是這麼說的
Constructs a type with all properties of Type set to optional.
This utility will return a type that represents all subsets of a give type.
對岸碼農基本上直接翻譯再加上互相抄來抄去,描述都只有一種
Partial 可以快速把某个接口类型中定义的所有属性变成可选的。
其實不完全正確。因為 Partial 並非像上述所說直接把介面中的屬性變成可選,事實上它會複製一份 Type,並將屬性全部設置為可選的,也就是將所有屬性加上 ?
,所以它是產生了一個新的 Type,並非改變原始型別,舉個例子:
interface Student {
id: number
name: string
address: string
}
const Andy: Student = {
id: 1,
name: 'Andy'
}
先定義 Student 介面,接著宣告型別為 Student 的變數,因為未分配 address
的關係,我們得到以下錯誤
該錯誤表示 address 在 Student 型別中是必要的屬性,在不改變 Student 定義下,有兩種解決方法,一種是分配 address 毫無懸念,另一種是定義新的介面,將 address
設為可選的,像是這樣
interface NewStudent {
id: number
name: string
address?: string // 定義為可選的
}
// 沒有填寫 address 也不會報錯
const Andy: NewStudent = {
id: 1,
name: 'Andy'
}
嗯...好像有點奇怪,相似的介面為什麼要寫兩個?假若再添加一個新屬性 age,其情況與 address 相同,不就要反覆定義新的介面?而這些介面差異只在於屬性的可選性...
此時就是端出 Partial 的好時機,我們不需要定義新的介面,而是讓 Partial 去複製一份新的物件型別,其所有屬性就會變成可選。
改良上面的例子
interface Student {
id: number
name: string
address: string
}
const Andy: Partial<Student> = {
id: 1,
name: 'Andy'
}
如此一來,不定義 address 也不會報錯,就算不定義其他屬性也不會報錯,因為此時 Andy 的型別 Partial<Student>
會長這樣
{
id?: number
name?: string
address?: string
}
發現了嗎?所有 property 都是 optional!所以說 Partial 到底是如何實現的?來看原始碼
/**
* Make all properties in T optional
*/
type Partial<T> = {
[P in keyof T]?: T[P];
};
只有一句重點 [P in keyof T]? :T[P]
(關於 in
和 keyof
不再贅述)
解析
在 type 內部宣告一個變數 P,迭代型別 T 的每個 property,將每次遍歷結果分配給 P 以及設置 P 為 optional。
定義新的 type 為 Partial<Student>
interface Student {
id: number
name: string
address: string
age: number
}
type StudentInfo = Partial<Student>
檢查 StudentInfo
將 Student 型別分配給 Partial<T>
,它會返回一個新的型別 StudentInfo,其所有的 property 皆設置為可選的。
了解原理後,嘗試自行實作 Partial
type StudentPartial<T> = {
[P in keyof T]?: T[P]
}
const Andy: StudentPartial<Student> = {
id: 1,
name: 'Andy'
}
一一拆解後其實並不難,宛如一塊小蛋糕,適時地使用 Partial,讓程式碼更乾淨簡潔吧!
Thanks for reading the article 🌷 🌻 🌼
If you like it, please don't hesitate to click heart button ❤️
or follow my GitHub ⭐ I'd appreciate it.
Posted on November 23, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 29, 2024
November 29, 2024