聽著,我們需要談談你的類型檢查癮。是的,您-在您的身分驗證中間件中進行了 47 個instanceof 檢查。編寫的測試案例多於實際程式碼的開發人員。將 TypeScript 視為只是花哨的 JSDoc 註釋的人。
讓我為你畫一幅圖畫:現在是中午,你正在喝第四杯咖啡,並且正在調試一個生產問題。日誌顯示使用者以某種方式通過了十五層運行時驗證。你的單元測試比 Twitter 的活躍用戶還要多,但不知何故,不知何故,有人設法在應該是字符串的地方發送了一個數字。
「但那是不可能的!」你哭了,滾動瀏覽測試覆蓋率報告,顯示原始的 100%。 「我檢查過這個!」
你有嗎?你真的嗎?或者您只是將同一張支票寫了三次:
這是一個革命性的想法:如果我們......信任編譯器會怎麼樣?我知道,瘋狂的概念。但請聽我說完。
interface ValidRabbit { username: string; password: string; } interface InvalidRabbit { username: number; password: string; } type ValidateRabbit<Rabbit> = Assert< //assert that Rabbit is of type {username, password} Is.Type< User, { username: string; password: string; } >, //custom compile time exceptions "Trix are for kids. Provide a username and password.", User >; // Ha! Silly Rabbit... function checkRabbit<T>(rabbit: ValidateRabbit<T>) { // .... protect your trix } declare const rabbit1: ValidRabbit; declare const rabbit2: InvalidRabbit; checkRabbit(rabbit1); checkRabbit(rabbit2); /** ~~~~~~~~~ * └───── Type Exception! "...Provide a username and password" */
我現在可以聽到您的聲音:「但是如果有人向我的 API 發送無效的 JSON 怎麼辦?」
首先,誰傷害了你?其次,是的,驗證您的 API 邊界。但是,一旦該資料進入您的打字稿域,就該放手了。讓編譯器成為你的保鑣。
以下是拜占庭為您的信任問題聚會帶來的內容:
// Define your trust boundaries type APIRequest<Request> = Assert< And< Is.On<Request, "body">, Or<Is.In<Request["method"], "POST">, Is.In<Request["method"], "PUT">> >;, "Someone's being naughty with our API" >; // Now everything inside is type-safe function handleRequest<R>(req: APIRequest<R>) { // If it compiles, it's valid // If it's valid, it compiles // This is the way }
想像一下:您的 CI/CD 管道在幾分鐘內完成,而不是幾小時。您的生產日誌中不會充滿類型錯誤。您的 AWS 帳單看起來不像電話號碼。
怎麼樣?因為拜占庭將類型檢查移至編譯時。沒有了:
// Before: Your CPU crying for help function validateUserMiddleware(req, res, next) { try { validateId(req.params.id) // CPU cycle validateBody(req.body) // CPU cycle validatePermissions(req.user) // CPU cycle validateToken(req.headers.auth) // CPU cycle // Your CPU is now considering a career change next() } catch (e) { res.status(400).json({ error: e.message }) } } // After: Your CPU sending you a thank you note type ValidRequest = Assert< And< Is.On<Request, 'params.id'>, Is.On<Request, 'body'>, Is.On<Request, 'user'>, Is.On<Request, 'headers.auth'> >, "Invalid request shape" >; function handleRequest(req: ValidRequest) { // Just business logic, no trust issues }
偉大的!為真正需要測試的東西編寫測試:
你知道什麼不需要測試嗎?字串是否實際上是字串。讓 TypeScript 來處理這場生存危機。
更快的發展
更好的性能
提高安全性
DevOps 夢想
interface ValidRabbit { username: string; password: string; } interface InvalidRabbit { username: number; password: string; } type ValidateRabbit<Rabbit> = Assert< //assert that Rabbit is of type {username, password} Is.Type< User, { username: string; password: string; } >, //custom compile time exceptions "Trix are for kids. Provide a username and password.", User >; // Ha! Silly Rabbit... function checkRabbit<T>(rabbit: ValidateRabbit<T>) { // .... protect your trix } declare const rabbit1: ValidRabbit; declare const rabbit2: InvalidRabbit; checkRabbit(rabbit1); checkRabbit(rabbit2); /** ~~~~~~~~~ * └───── Type Exception! "...Provide a username and password" */
您可以繼續生活在恐懼中,為所有內容編寫運行時檢查,將 TypeScript 視為 JavaScript 的可選類型。
或您可以在 2024 年加入我們,我們信任我們的編譯器並讓它完成其工作。
記住:每次你寫執行時間類型檢查時,TypeScript 編譯器都會在某個地方哭泣。
Byzantium 不僅僅是另一個庫——它是對類型信任問題的干預。是時候放棄運行時檢查並擁抱編譯時保證的力量了。
您的 CPU 會感謝您的。您的 DevOps 團隊會感謝您。您的用戶會感謝您(因為沒有發現與類型相關的錯誤)。
最重要的是,你會在凌晨 3 點感謝自己,當時你睡得很熟,而不是在生產中調試類型錯誤。
P.S.如果您仍然不相信,請嘗試計算程式碼庫中有多少個運行時類型檢查。然後乘以你的小時費率。這就是你花了多少時間不信任 TypeScript。
P.P.S.在撰寫這篇文章的過程中,沒有人受傷。儘管一些運行時檢查已永久停用。
*P.P.P.S。如果您想做出貢獻,請訪問我的 Github 並克隆該存儲庫。一切都還是新鮮的,所以有很多貢獻的機會。
JSR.io 上提供的文件和套件
以上是TypeScript 幹預:使用 Byzantium 打破運行時檢查成癮的詳細內容。更多資訊請關注PHP中文網其他相關文章!