تایپاسکریپت - عدم توانایی در استفاده از 'نوع ایندکس' با یک متغیر رشتهای
من دارم سعی میکنم فیلدهای یک شیء را اگر مقداری وجود داشته باشد معکوس کنم، اما خطایی دریافت میکنم که نمیتوانم آن را رمزگشایی کنم.
interface Control {
name1: boolean;
name2: boolean;
...
}
const values = ['name1', 'name2', ...];
const control: Control = {
name1: false,
name2: false,
...
}
for (const value of values) {
if ((value in control) {
control[value] = !control[value]; // error
}
}
پیغام خطا:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Control'.
No index signature with a parameter of type 'string' was found on type 'Control'.ts(7053)
با این حال، خطا برطرف میشود اگر من یکی از فیلدهای شیء را صریحاً منتقل کنم، مانند control['name1']. آیا چیزی هست که من متوجه آن نشدهام؟
پاسخ شماره ۱
TypeScript نمیداند که آرایه values شما یک آرایه از رشتههای خاص است، فقط میداند که این یک string[] است. این را امتحان کنید:
interface Control {
name1: boolean;
name2: boolean;
}
const values = ['name1', 'name2'] as const;
const control: Control = {
name1: false,
name2: false,
}
for (const value of values) {
if (value in control) {
control[value] = !control[value]; // error
}
}
محیط بازی تایپاسکریپت
آن as const به TypeScript میگوید که نوع values را به صورت دقیقتر مشخص کند تا در این مورد ['name1', 'name2'] باشد، بنابراین وقتی در حال تکرار روی آن هستید، value به عنوان 'name1' | 'name2' نوعدهی میشود و TypeScript متوجه میشود که میتوان از این مقادیر برای ایندکس کردن یک Control استفاده کرد.
پاسخ شماره ۲
متغیر value میتواند در طول اجرای برنامه هر مقداری باشد و تایپاسکریپت هیچ اطلاعی ندارد که این یک کلید معتبر تعریفشده درون شیء control است. بنابراین نمیتواند به سادگی نوع مقدار control[value] را استنتاج کند.
با این حال، رفع مشکل بسیار ساده است، تنها کاری که باید انجام شود این است که به تایپاسکریپت بگوییم آرایه values فقط شامل کلیدهای معتبر از نوع Control است با استفاده از نحو keyof Control:
const values: (keyof Control)[] = ['name1', 'name2'];
در اینجا یک لینک به زمین بازی وجود دارد.
