رسیدگی به خطاها در TypeScript: متوقف کردن پرتاب ، شروع به بازگشت

در TypeScript ، ما اغلب فرض می کنیم که توابع همیشه برگرد مقادیر مورد انتظار آنها اما چه اتفاقی می افتد که مشکلی پیش بیاید؟ بسیاری از کارکردها می توانند خطاها را پرتاب کنید، اما TypeScript هنوز هم آنها را تایپ می کند که گویی همیشه موفق می شوند. این می تواند به تصادفات غیر منتظره و اطلاعات گمراه کننده منجر شود.
بیایید این را با یک مثال تجزیه کنیم و ببینیم چگونه neverthrow
آن را برطرف می کند – حتی بدون نیاز به انواع صریح!
مشکل: استثنائات پنهان
بیایید بگوییم که ما تابعی داریم که سن کاربر را از یک پایگاه داده می گیرد. اگر شناسه کاربر نامعتبر باشد ، خطایی را به وجود می آورد.
function getUserAge(userId: number) {
if (userId < 0) throw new Error("Invalid user ID");
return 25; // Fake age for demo
}
const age = getUserAge(-1); // This might throw an error, yet it's typed as number
console.log("User age:", age);
چرا این یک مشکل است؟
-
نوع گمراه کننده: Infers Typescript
getUserAge()
به عنوان تعداد بازگشت ، حتی اگر می تواند خطایی را به وجود آورد. - تصادفات غیر منتظره: اگر یک شناسه کاربر نامعتبر منتقل شود ، این عملکرد هرگز در واقع برمی گردد و به جای آن پرتاب می شود!
- بدون نوع ایمنی برای خطاها: هیچ چیز در امضای عملکرد وجود ندارد که ممکن است خطایی به ما هشدار دهد.
وقتی معلق هستید getUserAge
، TypeScript نادرست نشان می دهد:
function getRandomNumber(): number
راه حل: استفاده neverthrow
به جای پرتاب خطا ، بیایید استفاده کنیم neverthrow
برای بازگشت صریح آنها:
import { ok, err } from "neverthrow";
function getUserAge(userId: number) {
if (userId < 0) return err("Invalid user ID"); // Explicit error
return ok(25); // Success case
}
const ageResult = getUserAge(-1);
چه نوع متن به طور خودکار: به طور خودکار:
function getRandomNumber(): Err<never, "Invalid user ID"> | Ok<number, never>
-
Ok
-> در صورت موفقیت ، شماره ای را در خود جای داده است. -
Err
-> در صورت عدم موفقیت ، آن را نگه می دارد رشته خطای دقیقبشر
چرا این بهتر است؟
- دیگر استثنائی پنهان نیست: ما هرگز خطا نمی کنیم ، بنابراین برنامه ما هرگز به طور غیر منتظره خراب نمی شود.
-
انواع خطای دقیق تر: به جای استفاده از عمومی
string
یاError
، TypeScript به طور خودکار مقادیر خطای دقیق را به خود جلب می کند. - رسیدگی صریح و ایمن: از آنجا که نتیجه ما را وادار می کند تا هر دو مورد را اداره کنیم ، ما کد واضح تر و ایمن تر می نویسیم:
if (ageResult.isErr()) {
console.error("Error:", ageResult.error); // Typed as "Invalid user ID"
} else {
console.log("User age:", ageResult.value); // Typed as number
}
حتی بهتر: دست زدن به عملکرد
به جای استفاده if
اظهارات ، ما می توانیم نتیجه را با آن زنجیر کنیم .map()
وت .mapErr()
:
ageResult
.map(age => console.log("User age:", age)) // Runs if success
.mapErr(error => console.error("Error:", error)); // Runs if failure
این باعث می شود کد ما تمیزتر و خواندن آسان تر شود!
غذای نهایی
با استفاده از neverthrow
استثنائات پنهان را از بین می برد و کد را قابل پیش بینی تر می کند. به جای پرتاب خطا ، ما آنها را صریح باز می گردانیم ، و اطمینان می دهیم که TypeScript به درستی از موارد موفقیت و عدم موفقیت در آن جلوگیری می کند.
این رویکرد مانع از گمراه کننده انواع و تصادفات غیر منتظره ضمن مجبور کردن خطای مناسب می شود. TypeScript به طور طبیعی انواع دقیقی را نشان می دهد و منجر به کاربردهای تمیزتر ، ایمن تر و قابل اطمینان تر می شود.