Skip to content

Commit cc8d193

Browse files
committed
Calculate readonly? on union/intersection creation
1 parent 931839c commit cc8d193

File tree

2 files changed

+9
-5
lines changed

2 files changed

+9
-5
lines changed

src/compiler/checker.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -4197,6 +4197,7 @@ namespace ts {
41974197
let props: Symbol[];
41984198
// Flags we want to propagate to the result if they exist in all source symbols
41994199
let commonFlags = (containingType.flags & TypeFlags.Intersection) ? SymbolFlags.Optional : SymbolFlags.None;
4200+
let isReadonly = false;
42004201
for (const current of types) {
42014202
const type = getApparentType(current);
42024203
if (type !== unknownType) {
@@ -4209,6 +4210,9 @@ namespace ts {
42094210
else if (!contains(props, prop)) {
42104211
props.push(prop);
42114212
}
4213+
if (isReadonlySymbol(prop)) {
4214+
isReadonly = true;
4215+
}
42124216
}
42134217
else if (containingType.flags & TypeFlags.Union) {
42144218
// A union type requires the property to be present in all constituent types
@@ -4238,6 +4242,7 @@ namespace ts {
42384242
name);
42394243
result.containingType = containingType;
42404244
result.declarations = declarations;
4245+
result.isReadonly = isReadonly;
42414246
result.type = containingType.flags & TypeFlags.Union ? getUnionType(propTypes) : getIntersectionType(propTypes);
42424247
return result;
42434248
}
@@ -11975,11 +11980,9 @@ namespace ts {
1197511980
// Variables declared with 'const'
1197611981
// Get accessors without matching set accessors
1197711982
// Enum members
11978-
// Unions and intersections of the above
11979-
if (symbol.flags & SymbolFlags.SyntheticProperty) {
11980-
return forEach(symbol.declarations, decl => isReadonlySymbol(getSymbolOfNode(decl)));
11981-
}
11982-
return symbol.flags & SymbolFlags.Property && (getDeclarationFlagsFromSymbol(symbol) & NodeFlags.Readonly) !== 0 ||
11983+
// Unions and intersections of the above (unions and intersections eagerly set isReadonly on creation)
11984+
return symbol.isReadonly ||
11985+
symbol.flags & SymbolFlags.Property && (getDeclarationFlagsFromSymbol(symbol) & NodeFlags.Readonly) !== 0 ||
1198311986
symbol.flags & SymbolFlags.Variable && (getDeclarationFlagsFromSymbol(symbol) & NodeFlags.Const) !== 0 ||
1198411987
symbol.flags & SymbolFlags.Accessor && !(symbol.flags & SymbolFlags.SetAccessor) ||
1198511988
(symbol.flags & SymbolFlags.EnumMember) !== 0;

src/compiler/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2104,6 +2104,7 @@ namespace ts {
21042104
members?: SymbolTable; // Class, interface or literal instance members
21052105
exports?: SymbolTable; // Module exports
21062106
globalExports?: SymbolTable; // Conditional global UMD exports
2107+
/* @internal */ isReadonly?: boolean; // readonly? (set only for intersections and unions)
21072108
/* @internal */ id?: number; // Unique id (used to look up SymbolLinks)
21082109
/* @internal */ mergeId?: number; // Merge id (used to look up merged symbol)
21092110
/* @internal */ parent?: Symbol; // Parent symbol

0 commit comments

Comments
 (0)