Skip to content

Commit 53de336

Browse files
Don't propagate partial union/intersection properties between caches (microsoft#58083)
Co-authored-by: Jake Bailey <5341706+jakebailey@users.noreply.github.com>
1 parent 5c55ce1 commit 53de336

6 files changed

+54
-7
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15099,16 +15099,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1509915099
// these partial properties when identifying discriminant properties, but otherwise they are filtered out
1510015100
// and do not appear to be present in the union type.
1510115101
function getUnionOrIntersectionProperty(type: UnionOrIntersectionType, name: __String, skipObjectFunctionPropertyAugment?: boolean): Symbol | undefined {
15102-
let property = type.propertyCacheWithoutObjectFunctionPropertyAugment?.get(name) ||
15103-
!skipObjectFunctionPropertyAugment ? type.propertyCache?.get(name) : undefined;
15102+
let property = skipObjectFunctionPropertyAugment ?
15103+
type.propertyCacheWithoutObjectFunctionPropertyAugment?.get(name) :
15104+
type.propertyCache?.get(name);
1510415105
if (!property) {
1510515106
property = createUnionOrIntersectionProperty(type, name, skipObjectFunctionPropertyAugment);
1510615107
if (property) {
1510715108
const properties = skipObjectFunctionPropertyAugment ?
1510815109
type.propertyCacheWithoutObjectFunctionPropertyAugment ||= createSymbolTable() :
1510915110
type.propertyCache ||= createSymbolTable();
1511015111
properties.set(name, property);
15111-
if (skipObjectFunctionPropertyAugment && !type.propertyCache?.get(name)) {
15112+
// Propagate an entry from the non-augmented cache to the augmented cache unless the property is partial.
15113+
if (skipObjectFunctionPropertyAugment && !(getCheckFlags(property) & CheckFlags.Partial) && !type.propertyCache?.get(name)) {
1511215114
const properties = type.propertyCache ||= createSymbolTable();
1511315115
properties.set(name, property);
1511415116
}

tests/baselines/reference/checkJsxChildrenCanBeTupleType.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Assignability cache: 2,200 / 2,200 (nearest 100)
55
Type Count: 7,800 / 7,800 (nearest 100)
66
Instantiation count: 90,000 / 90,000 (nearest 500)
7-
Symbol count: 66,500 / 66,500 (nearest 500)
7+
Symbol count: 67,000 / 67,000 (nearest 500)
88

99
=== checkJsxChildrenCanBeTupleType.tsx ===
1010
/// <reference path="react16.d.ts" />

tests/baselines/reference/infiniteConstraints.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Assignability cache: 200 / 200 (nearest 100)
55
Type Count: 1,000 / 1,000 (nearest 100)
66
Instantiation count: 2,500 / 2,500 (nearest 500)
7-
Symbol count: 25,500 / 26,000 (nearest 500)
7+
Symbol count: 25,500 / 25,500 (nearest 500)
88

99
=== infiniteConstraints.ts ===
1010
// Both of the following types trigger the recursion limiter in getImmediateBaseConstraint

tests/baselines/reference/styledComponentsInstantiaionLimitNotReached.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
=== Performance Stats ===
44
Identity cache: 200 / 200 (nearest 100)
55
Assignability cache: 13,300 / 13,500 (nearest 100)
6-
Type Count: 27,300 / 27,600 (nearest 100)
6+
Type Count: 27,200 / 27,600 (nearest 100)
77
Instantiation count: 374,500 / 375,500 (nearest 500)
88
Symbol count: 92,000 / 92,000 (nearest 500)
99

tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Assignability cache: 2,200 / 2,300 (nearest 100)
55
Type Count: 6,900 / 7,000 (nearest 100)
66
Instantiation count: 73,000 / 73,500 (nearest 500)
7-
Symbol count: 70,500 / 70,500 (nearest 500)
7+
Symbol count: 70,500 / 71,000 (nearest 500)
88

99
=== test.tsx ===
1010
/// <reference path="react16.d.ts" />
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @strict: true
4+
// @lib: esnext
5+
6+
//// interface ComponentOptions<Props> {
7+
//// setup?: (props: Props) => void;
8+
//// name?: string;
9+
//// }
10+
////
11+
//// interface FunctionalComponent<P> {
12+
//// (props: P): void;
13+
//// }
14+
////
15+
//// type ConcreteComponent<Props> =
16+
//// | ComponentOptions<Props>
17+
//// | FunctionalComponent<Props>;
18+
////
19+
//// type Component<Props = {}> = ConcreteComponent<Props>;
20+
////
21+
//// type WithInstallPlugin = { _prefix?: string };
22+
////
23+
////
24+
//// /**/
25+
//// export function withInstall<C extends Component, T extends WithInstallPlugin>(
26+
//// component: C | C[],
27+
//// target?: T,
28+
//// ): string {
29+
//// const componentWithInstall = (target ?? component) as T;
30+
//// const components = Array.isArray(component) ? component : [component];
31+
////
32+
//// const { name } = components[0];
33+
//// if (name) {
34+
//// return name;
35+
//// }
36+
////
37+
//// return "";
38+
//// }
39+
40+
verify.noErrors();
41+
42+
goTo.marker();
43+
edit.insert("type C = Component['name']");
44+
45+
verify.noErrors();

0 commit comments

Comments
 (0)