Suggest an editImprove this articleRefine the answer for “Readonly | optional intersections”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)When properties with the same name intersect, the **property type** is taken as the intersection of the types (`T1 & T2`), and `readonly` "wins": if the property is `readonly` in at least one type, it will be `readonly` in the intersection too. **Key point:** required-ness also "wins" - if the property is required in one type, it becomes required in the intersection; it stays optional only if it is optional in all parts.Shown above the full answer for quick recall.Answer (EN)ImageIn short: - When properties with the same name intersect, the **property type** is taken as the intersection of the types (`T1 & T2`). - `readonly` **"wins"**: if the property is `readonly` in at least one type, it will be `readonly` in the intersection. - **Required-ness "wins"**: if the property is required in one type, it becomes required in the intersection; it stays optional only if it is optional in all parts. Below, illustrated. --- ## 1) `readonly` × a regular field ```javascript type A = { readonly x: number }; type B = { x: number }; type C = A & B; // { readonly x: number } ``` - It has to satisfy **both** types at once -> `x` cannot be changed => `readonly`. - If the types are incompatible, you get an unrepresentable result: ```javascript type D = { readonly x: number } & { x: string }; // x: number & string -> never -> the whole type becomes unrepresentable (effectively never) ``` > Rule: for the same key, the `readonly` modifier in an intersection is always kept if it appears in at least one member. --- ## 2) How an intersection affects `optional` (`?`) ### a) Optional × required -> **required** ```javascript type A = { x?: number }; type B = { x: number }; type C = A & B; // { x: number } ``` - To satisfy `B`, `x` **must** exist; so the resulting property is required. ### b) Optional × optional (with compatible types) ```javascript type A = { x?: number }; type B = { x?: number }; type C = A & B; // { x?: number } ``` - The optionality is preserved, since the property is optional in both parts and the types are compatible. ### c) Optional × optional (with **incompatible** types) ```javascript type A = { x?: string }; type B = { x?: number }; type C = A & B; // { x?: never } ``` - Property type: `string & number` -> `never`. - Semantics of `x?: never`: the property **cannot be specified** (if you specify it, you cannot give it a valid value), but it **can be omitted**. - In effect, this behaves as if "property `x` doesn't exist". ### d) Optional × required (with incompatible types) ```javascript type A = { x?: string }; type B = { x: number }; type C = A & B; // { x: never } // required, but never realizable ``` - This produces a contradiction: the property is **required**, but its type is `never` => the intersection is unresolvable (effectively `never`). ### e) Mixing with `readonly` ```javascript type A = { readonly x?: number }; type B = { x: number }; type C = A & B; // { readonly x: number } ``` - Required-ness "wins", `readonly` is preserved. --- ## Cheat sheet (intuitive rules) - **Type**: `T = T1 & T2`. - **Required-ness**: if the property is required in **at least one** type -> in the intersection it is **required**; it's optional only if it's optional **everywhere**. - **readonly**: if `readonly` appears **anywhere** -> in the intersection it's `readonly`. - If the resulting property type becomes `never` and the property is **required** -> the whole type is not realizable (effectively `never`). If the resulting type is `never` and the property is **optional** -> the property is "forbidden to specify", but can be omitted.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.