خطای Object literal may only specify known properties در تایپ اسکریپت
۱۷ شهریور ۱۳۹۹
دلیل خطای Object literal may only specify known properties تایپ اسکریپت بررسی وجود Property اضافی است تا مانع از پذیرش آن شود، در این مطلب به دو حالت مختلف تفسیر Interface در تایپ اسکریپت اشاره میکنیم و سپس راه حلهای مختلف حل این مشکل را معرفی میکنیم.
Excess Property Checks یا بررسی پراپرتی اضافی
مثال زیر را به عنوان Interface و متد زیر را در نظر بگیرید.
دو حالت مختلف کلی را برای شیوهی تفسیر این interface در تایپ اسکریپت تصور کرد:
۱ـ تفسیر بسته یا Closed interpretation: در این حالت هر object که دقیقا شامل پراپرتیهای اینترفیس هستن قابل قبولاند که در این بین پراپرتی که الزامی نیست مثل y در مثال بالا میتواند حضور داشته باشد یا خیر اما وجود x الزامی است و درصورت وجود یک پراپرتی اضافی (Excess Property) مثل z با خطا روبرو خواهیم شد.
computeDistance({ x:1, y:2, z:3});// Object literal may only specify known properties, and 'z' does not exist in type 'Point'.(2345)
۲ـ تفسیر باز یا Opened interpretation: در این حالت کافیست یک شیئ دارای یک زیر مجموعهای از اینترفیس مورد نظر باشد برای مثال آبجکتی شامل پراپرتی x و z در این حالت قابل قبول هست چون دارای پراپرتیهای الزامی اینترفیس Point است و از طرفی دیگر داشتن پراپرتی اضافی z مانند مثال قبل در این حالت باعت ایجاد خطا نمیشود و پذیرفتهاست.
Excess Property Checks یا بررسی پراپرتی اضافی چه کمکی میکند؟
زمانی که ورودی یک متد را با یک متغیر که بصورتهای مختلف در برنامه ایجاد میشود مقداردهی میکنیم Opened interpretation رخ میدهد و بررسی وجود پراپرتی اضافی بررسی نمیشود ولی در حالتی که خودمان بصورت یک Object literal به عنوان ورودی تابع در نظر میگیریم
Closed interpretation رخ میدهد و اگر در زمان نوشتن پراپرتیهای آبجکت خطای تایپی رخ دهد که در این حالت احتمال بیشتری دارد تایپ اسکریپت آن را به عنوان یک پراپرتی اضافی در نظر گرفته و هشدار میدهد. مثال زیر را در نظر بگیرید:
فرض کنید بصورت زیر و به روش Object literal میخواستیم ورودی تابع computeFullName را مقداردهی کنیم ولی بجای middle به اشتباه mdidle تایپ کردیم.
همین طور که مشاهده میکنید به لطف وجود Excess Property Checks در تایپ اسکریپت این هشدار واضح را مبنی بر اینکه احتمالا اشتباهاً بجای middle عبارت mdidle را تایپ کردیم نمایش داده میشود.
روشهای جلوگیری از بررسی وجود پراپرتیهای اضافی
۱ـ استفاده از یک متغیر واسط برای مقداردهی به متد یک تابع
۲ـ استفاده از type assertion بصورت زیر
۳ـ بازنویسی متد computeDistance1 و استفاده از یک type parameter
۴ـ بازنویسی اینترفیس Point با اضافه کردن یک Index signature بصورت زیر برای اینکه پراپرتیهای اضافی را بپذیرد
در ادامه یک مثالی را بررسی میکنیم که Excess Property Checks تایپ اسکریپت مشکل ایجاد میکند.
در مثال زیر میخواهیم
Incrementor را پیادهسازی کنیم ولی تایپ اسکریپت اجازهی اضافه کردن یک پراپرتی جدید به عنوان counter را نمیدهد.
حتی زمانیکه از type assertion استفاده میکنیم همچنان مشکل باقی است.
برای حل این مشکل میتوان از دو روش زیر استفاده کرد:
۱ـ استفاده از متغیر واسط
۲ـ در صورت امکان اضافه کردن Index signature به اینترفیس Incrementor