ساخت یک نوع از کلیدهای یک const در تایپاسکریپت
من یک دیکشنری از MessageTemplates دارم که در طول زمان در حال ساخت آن هستم و امیدوار بودم که بتوانم سپس یک type در TypeScript صادر کنم که مجموعه ویژگیهایی که از ساختار MessageTemplates آویزان هستند را نشان میدهد، اما با آن مخالفت میکند.
احساس میکنم دارم کار احمقانهای انجام میدهم، اما اینقدر طولانی به این نگاه کردهام که نتوانم سوال نپرسم.
توجه کنید، من همین الان فهمیدم که اگر از ساختار کلاس استفاده کنم — با متدهای استاتیک که به آن متصل میشوند — کار میکند اما هنوز هم متعجبم که چرا نحو شیء ساده کار نمیکند.
پاسخ شماره ۱
مشکلی که شما دارید این است که MessageTemplates یک مقدار است، نه یک نوع، و عملگر پرس و جو از نوع نمایه keyof روی نام یک نوع عمل میکند، نه یک مقدار. یک روش سرانگشتی برای تشخیص تفاوت این است که بفهمید آیا نام در جاوااسکریپت کامپایل شده ظاهر خواهد شد یا خیر. اگر در زمان اجرا ظاهر شود، احتمالاً یک مقدار است؛ اگر نه، احتمالاً یک نوع است. در مورد شما، MessageTemplates به صورت یک متغیر در زمان اجرا وجود خواهد داشت، بنابراین یک مقدار است.
چیزی که میخواهید keyof را روی آن اعمال کنید، MessageTemplates نیست، بلکه نوع مقدار MessageTemplates است. و خوشبختانه میتوانید از عملگر پرسوجوی نوع typeof برای به دست آوردن نوع یک مقدار استفاده کنید. بنابراین typeof X برای مقداری به نام X نوع آن مقدار را برمیگرداند.
(این نباید با عملگر typeof زمان اجرا اشتباه گرفته شود، جایی که typeof X روی یک مقدار به نام X عمل کرده و رشتهای مانند "number" یا "boolean" در زمان اجرا برمیگرداند. شما میتوانید از زمینه بفهمید کدام مورد است. اگر typeof در جاوااسکریپت کامپایلشده ظاهر شود، آن همان عملگر زمان اجرا است. اگر typeof بخشی از حاشیه نوع یا اعلان نوع باشد و قبل از کامپایل شدن به جاوااسکریپت حذف شود، آن عملگر پرسوجوی نوع است. متأسفم؛ استفاده از همان کلمه کلیدی برای چیزهای مختلف گیجکننده است، اما این همان طوری است که هست. حدس میزنم طراحان زبان ترجیح میدهند از کلمات کلیدی که قبلاً رزرو شدهاند دوباره استفاده کنند تا کدهای موجود جاوااسکریپت خراب نشوند. یا فکر میکنند سرگرمکننده است که مردم تمام این هشدارها را به توضیحات خود اضافه کنند.)
برای جمعبندی: شما نمیخواهید keyof MessageTemplates، بلکه میخواهید «keyof نوع MessageTemplates»، که برابر است با keyof (typeof MessageTemplates). میتوانید پرانتزها را حذف کنید: keyof typeof MessageTemplates:
export type IMessageTemplateType = keyof typeof MessageTemplates
// type IMessageTemplateType = "upcomingUpload" | ...
امیدوارم کمک کند. موفق باشید!
