تایپاسکریپت: چرا undefined گزینهای نیست اگر نوع، ترکیبی از آرایه خالی و آرایه داده باشد هنگام دسترسی به یک مورد
آیا کسی میتواند این را توضیح دهد؟
چرا undefined یک گزینه نیست اگر نوع، یک اجتماع از آرایه خالی و آرایه داده باشد هنگام دسترسی به یک مورد
type emptyArray = []
type accessEmptyArray = emptyArray[0] // returns undefined
type validData = {id:number, name:string}
type someData = validData[] | []
type test = someData[0] // returns type validData but could also be undefined
فرض میکنم میتوانم این را با استفاده از یک ادعا حل کنم، اما این کار کد من را نسبتاً طولانی خواهد کرد.
من از این مشکل کاملاً شگفتزده شدهام، زیرا به نظر میرسد یک مشکل است که بهراحتی نادیده گرفته میشود و نوع مشکلی است که TS برای حل آن ایجاد شده، اما شاید من به معایب روش فرضی که فکر میکنم کار میکند، فکر نکردهام.
مثال: زمین بازی
پاسخ شماره ۱
این طبق طراحی است.
دسترسی فهرستشده به یک نوع، undefined برنمیگرداند.
type array = Array<string>;
type firstItemType = array[0] // string;
پاسخ شماره ۲
برای درک آن، لطفاً به این نکته آگاه باشید که:
type EmptyArray = []
type EmptyArray2 = never[]
هر دو EmptyArray و EmptyArray2 برابر هستند. آرایه خالی در تایپاسکریپت به عنوان never[] استنباط میشود.
این را امتحان کن:
type EmptyArray = []
type Item = EmptyArray[number] // never
بنابراین، اجتماع هر دو مجموعه خالی و غیر خالی به این صورت است:
type ValidData = { id: number, name: string }
type Union = Array<ValidData> | never[]
type NonEmptyElement = Array<ValidData>[number] // ValidData
type EmptyElement = never[][number] // never
type Result = Union[0] // ValidData | never -> ValidData
وقتی شما اتحاد آرایه خالی/غیر خالی را انجام میدهید و سعی میکنید اولین عنصر را بدست آورید، اساساً اتحاد ValidData | never را بدست میآورید، که برابر است با فقط ValidDate.
اگر کنجکاو هستید بدانید چرا never در هیچ اتحادی بیمعنی است، این پاسخ را ببینید
در مورد خطا در:
type emptyArray = []
type accessEmptyArray = emptyArray[0] // returns undefined
این به این دلیل است که emptyArray هیچ عنصری ندارد، و تایپ اسکریپت حتی اجازه استفاده از 0 را هم نمیدهد، با این حال، هنوز میتوانید از اندیس آرایه استفاده کنید:
type accessEmptyArray = emptyArray[number] // never
این به این دلیل است که Array این امضای نوع را دارد:
interface Array<T> {
[n: number]: T
}
