typescript - تفاوت بین Readonly<[]> و ReadOnlyArray<>


کد 1:

let readonlyArray: ReadonlyArray<string | number> = ["test", 1, 1];

کد ۲:

let readonlyArray: Readonly<[string, number]> = ["test", 1, 1];

به نظر میرسد هر دو خط کد کارهای مشابهی انجام میدهند. من نمیدانم تفاوت بین اعلان آرایه به عنوان ReadOnly و ReadOnlyArray چیست.

همچنین، کدام یک برای عملکرد بهترین است و چرا؟

پاسخ شماره ۱

از نظر عملکرد، نباید تفاوتی بین این دو وجود داشته باشد، زیرا نوعها در زمان اجرا حذف میشوند و همان جاوااسکریپت اجرا خواهد شد بدون توجه به نوعها

در زمان کامپایل تفاوت اساسی بین این دو نوع وجود دارد:

Readonly<T> - نوعی است که شکل مشابه T دارد اما تمام ویژگیهای آن فقط برای خواندن هستند. در مورد شما، T از نوع تاپل [string, number] است، بنابراین تمام ویژگیهای آرایه را دارد و همچنین اندیسهای 0 و 1 را نیز دارد. بنابراین میتوانیم متد push را صدا بزنیم، اما نمیتوانیم متد concat را دوباره اختصاص دهیم.

let readonlyArray: Readonly<[string, number]> = ["test", 1, 1];
readonlyArray.concat = ()=> {} // Not valid, concat is readonly 
readonlyArray.push(1); // This is valid 
readonlyArray[1] =  ""; // Invalid we cannot change a property by indexing 
readonlyArray[3] =  ""; // Valid as it was not in the original tuple type 

ویرایش: از نسخه 3.4، تایپاسکریپت رفتار تایپهای نگاشتهشده روی آرایهها و تاپلها را تغییر داده است، بنابراین Readonly<[string, number]> اکنون معادل یک تاپل فقطخواندنی readonly [string, number] است، بنابراین خطاها کمی متفاوت هستند:

let readonlyArray: Readonly<[string, number]> = ["test", 1];
readonlyArray.concat = ()=> {} // Not valid, concat is readonly 
readonlyArray.push(1); // This is not valid, no push method anymore
readonlyArray[1] =  ""; // Invalid we cannot change a property by indexing 
readonlyArray[3] =  ""; // Invalid now tuple length preserved

</ویرایش>

ReadonlyArray<T> یک آرایهٔ واقعی فقطخواندنی است که هیچ متدی برای تغییر آرایه ندارد. در مورد شما، هر آیتم از آرایه میتواند یا یک string یا یک number باشد:

let readonlyArray2: ReadonlyArray<string | number> = ["test", 1, 1];
readonlyArray2.concat = ()=> []; // Valid we can set the concat property on the object 
readonlyArray2.push(1) // No push method, invalid
readonlyArray2[1] =  ""; // Invalid it is read only 
readonlyArray2[3] =  ""; // Invalid it is read only