تایپاسکریپت: محدود کردن نوع: تأیید عدم تعریف و در نتیجه حذف از نوع
هر دو این خطوط با خطای «Object possibly undefined» در _e[k] مواجه میشوند:
obj[k] = typeof _e[k] === "undefined" ? "" : _e[k].toString();
obj[k] = _e[k] === undefined ? "" : _e[k].toString();
کد _e[k] یک اتحاد از انواع مختلف است، بنابراین اعمال تبدیل نوع دستی قابل استفاده نیست. چگونه میتوانم از این خطا خلاص شوم؟
بهروزرسانی: بنابراین به صورت کلیتر، سوال من میتواند اینگونه بیان شود: آیا راهی وجود دارد که نوع یک متغیر را با بررسی در برابر نوعهای خاصی که باید مستثنی شوند محدود کنیم؟
مثال حداقلی:
class test {
a!: string;
b?: number;
}
const t: test = { a: "hi", b: 2 };
for (const k of Object.keys(t) as Array<keyof test>) {
console.log(t[k] == undefined ? "LOL" : t[k].toString());
}
پاسخ شماره ۱
یک باگ/مسئله طولانیمدت وجود دارد که TypeScript تحلیل جریان کنترل را برای محدود کردن نوع یک ویژگی انجام نمیدهد اگر کلید ویژگی یک متغیر باشد: microsoft/TypeScript#10530؛ این موضوع حل نشد زیرا رفع آن باعث کاهش شدید عملکرد میشد. در مورد شما، این بدان معناست که بررسیهای نوع حفاظتی روی _e[k] بر استفادههای بعدی از _e[k] تأثیری نخواهد داشت.
راه حل پیشنهادی من برای این، اختصاص دادن ویژگی دسترسی با اندیس به یک متغیر جدید و بررسی آن است:
const ek = _e[k]; // new variable
obj[k] = typeof ek === "undefined" ? "" : ek.toString(); // no error now
متغیر جدید ek آنالیز نوع جریان کنترل عادی را دریافت میکند، و محافظ نوع شما کار میکند.
امکانات دیگر برای کاربردهای مختلف:
اگر شما قبلاً در برابر
undefinedوnullبررسی کردهاید اما کامپایلر نمیتواند آن را تشخیص دهد، سادهترین تغییر، استفاده از عملگر تأیید غیر تهی!است:obj[k] = typeof _e[k] === "undefined" ? "" : _e[k]!.toString(); // non-null assertionشما میتوانید کد حذف نوع خود را به یک عبارت مستقل و خودکفا بازسازی کنید تا هرگز نیازی به بررسی مجدد مقدار اصلی نداشته باشید. به عنوان مثال:
obj[k] = (_e[k] || "").toString(); // refactorآن کد خاص فقط کار میکند و تنها مقادیر نادرست که
_e[k]میتواند داشته باشدundefinedو""هستند. اگر_e[k]میتوانست0باشد، آن نتیجه متفاوتی میداد. به طور کلی میتوانید یک تابع جدید بسازید تا هر کاری که میخواهید انجام دهد:function defined<T, U>(x: T | undefined, dflt: U): T | U { return typeof x !== "undefined" ? x : dflt; } obj[k] = defined(_e[k], "").toString(); // refactor 2
باشه، امیدوارم یکی از اینها کمک کند؛ موفق باشی!
لینک زمین بازی به کد
پاسخ شماره ۲
پس، یک راهحل (نسبتاً موقتی) که برای مورد استفاده من مناسب است (اما در بسیاری از سناریوهای دیگر مناسب نخواهد بود) این است:
obj[k] = _e[k] === undefined ? "" : String(_e[k]);
هنوز علاقهمند به پیشنهادهای (بهتر) هستم که در حالت عمومیتر کار کنند (به بهروزرسانی سؤال مراجعه کنید)
