嘿嘿~今天來跟大家聊聊 TypeScript 裡的 JSON 型別處理!
這可是個相當有趣又實用的話題,特別是當我們在處理物件序列化和反序列化時,這套「神奇的型別技巧」真的能夠幫助你寫出更安全、更乾淨的程式碼!
你可能會問:「TypeScript 處理 JSON 不就是 JSON.stringify
和 JSON.parse
嗎?」嗯,雖然這是真的,但我們要進一步考慮型別安全!TypeScript 讓我們不僅僅能正確序列化/反序列化資料,還可以確保這些操作在編譯時就能夠型別正確地推斷資料的結構。這樣我們不會踩坑,也不用擔心序列化後的物件會跟原來長得不一樣!😂
JSONified
型別讓我直接從程式碼開始講起!看看這段 TypeScript 代碼,它展示了如何處理物件中的 JSON 型別:
type JSONified<T> =
JSONifiedValue<T extends { toJSON(): infer U } ? U : T>;
這段程式碼的意思是,如果你的物件有 toJSON
方法,那我們就用它返回的型別來處理;如果沒有,則直接處理物件本身的型別。
這樣做的好處是什麼呢?假如我們有些物件(比如 Date
)需要轉換成更簡單的格式,我們可以通過 toJSON()
來控制返回的值,讓序列化的物件格式化得更適合 JSON。
這樣就能避免把複雜的物件直接序列化,讓程式碼更簡潔!
JSONifiedValue
的魔法接下來看看這個更具魔力的型別定義:
type JSONifiedValue<T> =
T extends string | number | boolean | null ? T :
T extends Function ? never :
T extends Array<infer U> ? JSONifiedArray<U> :
T extends object ? JSONifiedObject<T> :
never;
這裡的邏輯就有點細節了,但別擔心!我來幫你拆解:
string
、number
、boolean
和 null
是直接支援的,沒問題。() => {}
這種函式直接變成 JSON,那可不行喔!這裡會返回 never
,TypeScript 就會跳出來阻止你做錯事。Array<infer U>
來推導出陣列的元素型別,然後對每個元素進行遞歸處理。undefined
要怎麼辦?JSON 不支援 undefined
,那該怎麼辦?這裡我們用了一個很聰明的小技巧:
type UndefinedAsNull<T> = T extends undefined ? null : T;
我們把 undefined
轉換成 null
,這樣當你有一些屬性可能是 undefined
的時候,它們會在序列化後變成 null
,這樣就符合 JSON 標準了。是不是很聰明?!
這麼多技巧聽起來很強大,但在實際應用中也有幾個容易犯的小錯誤:
忘記處理 undefined
:這是非常常見的問題,許多開發者在序列化物件時忽略了 undefined
無法被 JSON 表示。如果沒有像上面那樣進行 undefined
到 null
的轉換,序列化時會出現資料丟失的情況。
函式試圖進行序列化:很多時候我們不小心會把函式也一併序列化,導致 JSON.stringify
出錯。記得,函式是無法被序列化的,所以要特別注意!
對複雜物件缺少 toJSON()
:如果物件太複雜,記得使用 toJSON()
方法來格式化它的輸出,否則序列化後可能得到一個非常笨重的 JSON 結構,或者有些無法序列化的屬性會被直接丟掉。
總結來說,這些型別技巧讓我們可以輕鬆、安全地處理 TypeScript 中的 JSON 操作,保證型別正確並且不會踩到常見的 JSON 陷阱。
當然,這裡還有一個實用的 Serializer
類別,讓我們可以輕鬆地序列化和反序列化物件,像這樣:
class Serializer<T> {
serialize(inp: T): string {
return JSON.stringify(inp);
}
deserialize(inp: string): JSONified<T> {
return JSON.parse(inp);
}
}
有了這個類別,你可以確保你的物件在進行 JSON 操作時,型別完全正確,這對於大型專案非常有用。
型別安全的 JSON 操作:透過 JSONified
型別,確保物件在序列化和反序列化時符合 JSON 結構。
處理 undefined
:使用 UndefinedAsNull
將 undefined
轉換為 null
,避免 JSON 不支援 undefined
的問題。
避免函式序列化:函式無法被序列化,要特別注意將其過濾掉,否則會導致錯誤。
Generator 函式與懶惰評估:使用 Generator 函式,按需生成資料,避免一次處理過多數據導致資源浪費。
高級型別處理:利用 Pick
、infer
等工具型別,優化物件的型別定義,使得 JSON 操作更加靈活與準確。
希望這些 TypeScript 型別處理的小撇步能幫助你更順利地應對 JSON 相關的挑戰!
程式開發總是充滿了各種細節和挑戰,但只要掌握了正確的工具和技巧,很多問題都能迎刃而解~✨
記住,下一次寫 TypeScript 時,別忘了這些小技巧,讓你的程式碼更加優雅、更加安全!
Happy Coding~ 💻🚀