Readonly | optional intersections
In 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 isreadonlyin at least one type, it will bereadonlyin 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 ->
xcannot 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
readonlymodifier 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,xmust 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
xdoesn'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 (effectivelynever).
e) Mixing with readonly
javascript
type A = { readonly x?: number };
type B = { x: number };
type C = A & B; // { readonly x: number }- Required-ness "wins",
readonlyis 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
readonlyappears anywhere -> in the intersection it'sreadonly. - If the resulting property type becomes
neverand the property is required -> the whole type is not realizable (effectivelynever). If the resulting type isneverand the property is optional -> the property is "forbidden to specify", but can be omitted.
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.