Skip to content

Commit 1c2f7f8

Browse files
committed
Improve efficiency of union/intersection resolved property caching
1 parent a6c5306 commit 1c2f7f8

File tree

2 files changed

+22
-22
lines changed

2 files changed

+22
-22
lines changed

src/compiler/checker.ts

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4754,28 +4754,26 @@ namespace ts {
47544754
}
47554755

47564756
function getPropertiesOfUnionOrIntersectionType(type: UnionOrIntersectionType): Symbol[] {
4757-
for (const current of type.types) {
4758-
for (const prop of getPropertiesOfType(current)) {
4759-
getUnionOrIntersectionProperty(type, prop.name);
4760-
}
4761-
// The properties of a union type are those that are present in all constituent types, so
4762-
// we only need to check the properties of the first type
4763-
if (type.flags & TypeFlags.Union) {
4764-
break;
4765-
}
4766-
}
4767-
const props = type.resolvedProperties;
4768-
if (props) {
4769-
const result: Symbol[] = [];
4770-
props.forEach(prop => {
4771-
// We need to filter out partial properties in union types
4772-
if (!(prop.flags & SymbolFlags.SyntheticProperty && (<TransientSymbol>prop).isPartial)) {
4773-
result.push(prop);
4757+
if (!type.resolvedProperties) {
4758+
const members = createMap<Symbol>();
4759+
for (const current of type.types) {
4760+
for (const prop of getPropertiesOfType(current)) {
4761+
if (!members.has(prop.name)) {
4762+
const combinedProp = getPropertyOfUnionOrIntersectionType(type, prop.name);
4763+
if (combinedProp) {
4764+
members.set(prop.name, combinedProp);
4765+
}
4766+
}
47744767
}
4775-
});
4776-
return result;
4768+
// The properties of a union type are those that are present in all constituent types, so
4769+
// we only need to check the properties of the first type
4770+
if (type.flags & TypeFlags.Union) {
4771+
break;
4772+
}
4773+
}
4774+
type.resolvedProperties = getNamedMembers(members);
47774775
}
4778-
return emptyArray;
4776+
return type.resolvedProperties;
47794777
}
47804778

47814779
function getPropertiesOfType(type: Type): Symbol[] {
@@ -4943,7 +4941,7 @@ namespace ts {
49434941
// these partial properties when identifying discriminant properties, but otherwise they are filtered out
49444942
// and do not appear to be present in the union type.
49454943
function getUnionOrIntersectionProperty(type: UnionOrIntersectionType, name: string): Symbol {
4946-
const properties = type.resolvedProperties || (type.resolvedProperties = createMap<Symbol>());
4944+
const properties = type.propertyCache || (type.propertyCache = createMap<Symbol>());
49474945
let property = properties.get(name);
49484946
if (!property) {
49494947
property = createUnionOrIntersectionProperty(type, name);

src/compiler/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2948,7 +2948,9 @@
29482948
export interface UnionOrIntersectionType extends Type {
29492949
types: Type[]; // Constituent types
29502950
/* @internal */
2951-
resolvedProperties: SymbolTable; // Cache of resolved properties
2951+
propertyCache: SymbolTable; // Cache of resolved properties
2952+
/* @internal */
2953+
resolvedProperties: Symbol[];
29522954
/* @internal */
29532955
resolvedIndexType: IndexType;
29542956
/* @internal */

0 commit comments

Comments
 (0)