چگونه مقدار یک Record را در تایپاسکریپت بخوانیم (راه درست)


من دو نوع زیر را دارم

type SortOption = string | Record<string, "desc" | "asc">
type Item = { name: string, value: SortOption}

حالا من چند مورد دارم:

const item: Item = {
  name: "myItem",
  value: {
    version: "desc"
  }
}

و من سعی میکنم مقدار version را در شیء value بخوانم

console.log(item.value.version) // prints "desc" but shows error

اما من خطا میگیرم:

Property 'version' does not exist on type 'SortOption'.
  Property 'version' does not exist on type 'string'.ts(2339)

در کنسول من واقعاً میتوانم ببینم که مقدار desc چاپ میشود اما این خطا را در VS Code دریافت میکنم. میتوانستم با تبدیل شیء SortOption به any از این خطا جلوگیری کنم

console.log((item.value as any).version) // prints "desc" but doesn't show error

اما این شبیه یک راهحل ناپاک به نظر میرسد و من میخواهم بدانم چگونه میتوانم این را به صورت صحیح حل کنم.

پاسخ شماره ۱

شما SortOption را به این نوع تعریف کردهاید:

type SortOption = string | Record<string, "desc" | "asc">

این بدان معناست که item.value ممکن است یک string باشد یا ممکن است یک Record<string, 'desc' | 'asc'> باشد.

به عنوان مثال، این نیز یک Item معتبر است:

const item: Item = {
  name: "myItem",
  value: 'a string'
}

// but now this will throw an exception at runtime:
item.value.version

و اگر میخواهید مقدار را مانند یک Record رفتار کنید، ابتدا باید در زمان اجرا ثابت کنید که واقعاً چنین چیزی است تا بتوان نوع آن را محدود کرد.

به عنوان مثال:

// if it's not a string, it must be the other thing.
if (typeof item.value !== 'string') {
    console.log(item.value.version) // fine
}

دیدن زمین بازی