Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Перетини readonly | optional». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)При перетині властивостей з однаковим ім'ям **тип властивості** береться як перетин типів (`T1 & T2`), а `readonly` "перемагає": якщо хоча б в одному типі властивість `readonly`, у перетині вона теж буде `readonly`. **Ключове:** обов'язковість також "перемагає" - якщо в одному типі властивість обов'язкова, у перетині вона стане обов'язковою; опціональною вона залишається лише якщо опціональна в усіх частинах.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)ЗображенняКоротко: - При перетині властивостей з однаковим ім'ям **тип властивості** береться як перетин типів (`T1 & T2`). - `readonly` **"перемагає"**: якщо хоча б в одному типі властивість `readonly`, у перетині вона буде `readonly`. - **Обов'язковість "перемагає"**: якщо в одному типі властивість обов'язкова, у перетині вона стане обов'язковою; опціональною залишається тільки якщо опціональна в усіх частинах. Нижче - наочно. --- ## 1) `readonly` × звичайне поле ```javascript type A = { readonly x: number }; type B = { x: number }; type C = A & B; // { readonly x: number } ``` - Має задовольняти **обом** типам одразу -> змінювати `x` не можна => `readonly`. - Якщо типи несумісні, вийде нереалізованість: ```javascript type D = { readonly x: number } & { x: string }; // x: number & string -> never -> тип цілком стає непредставимим (по суті, never) ``` > Правило: для однакового ключа модифікатор `readonly` у перетині завжди зберігається, якщо зустрічається хоча б в одному доданку. --- ## 2) Як перетин впливає на `optional` (`?`) ### a) Опціональне × обов'язкове -> **обов'язкове** ```javascript type A = { x?: number }; type B = { x: number }; type C = A & B; // { x: number } ``` - Щоб задовольнити `B`, `x` **має** існувати; отже, підсумкова властивість обов'язкова. ### b) Опціональне × опціональне (із сумісними типами) ```javascript type A = { x?: number }; type B = { x?: number }; type C = A & B; // { x?: number } ``` - Опціональність зберігається, оскільки в обох частинах властивість опціональна і типи сумісні. ### c) Опціональне × опціональне (із **несумісними** типами) ```javascript type A = { x?: string }; type B = { x?: number }; type C = A & B; // { x?: never } ``` - Тип властивості: `string & number` -> `never`. - Семантика `x?: never`: властивість **не можна вказувати** (якщо вкажеш - не зможеш дати коректне значення), але її **можна опустити**. - Фактично це поводиться так, ніби "властивості `x` немає". ### d) Опціональне × обов'язкове (із несумісними типами) ```javascript type A = { x?: string }; type B = { x: number }; type C = A & B; // { x: never } // обов'язкове, але ніколи не реалізовне ``` - Виходить суперечність: властивість **обов'язкова**, але її тип - `never` => перетин нерозв'язний (по суті, `never`). ### e) Змішування з `readonly` ```javascript type A = { readonly x?: number }; type B = { x: number }; type C = A & B; // { readonly x: number } ``` - Обов'язковість "перемагає", `readonly` зберігається. --- ## Пам'ятка (інтуїтивні правила) - **Тип**: `T = T1 & T2`. - **Обов'язковість**: якщо **хоча б в одному** типі властивість обов'язкова -> у перетині вона **обов'язкова**; опціональна лише якщо опціональна **всюди**. - **readonly**: якщо **хоча б десь** `readonly` -> у перетині `readonly`. - Якщо підсумковий тип властивості став `never`, а властивість **обов'язкова** -> весь тип не реалізовний (по суті, `never`). Якщо підсумковий тип `never`, а властивість **опціональна** -> властивість "заборонена до вказання", але може бути опущена.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.