Don't propagate partial union/intersection properties between caches (#58083)

Co-authored-by: Jake Bailey <5341706+jakebailey@users.noreply.github.com>
This commit is contained in:
Anders Hejlsberg 2024-04-09 11:39:44 -07:00 committed by GitHub
parent 5c55ce1ba2
commit 53de336e1e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 54 additions and 7 deletions

View File

@ -15099,8 +15099,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// these partial properties when identifying discriminant properties, but otherwise they are filtered out
// and do not appear to be present in the union type.
function getUnionOrIntersectionProperty(type: UnionOrIntersectionType, name: __String, skipObjectFunctionPropertyAugment?: boolean): Symbol | undefined {
let property = type.propertyCacheWithoutObjectFunctionPropertyAugment?.get(name) ||
!skipObjectFunctionPropertyAugment ? type.propertyCache?.get(name) : undefined;
let property = skipObjectFunctionPropertyAugment ?
type.propertyCacheWithoutObjectFunctionPropertyAugment?.get(name) :
type.propertyCache?.get(name);
if (!property) {
property = createUnionOrIntersectionProperty(type, name, skipObjectFunctionPropertyAugment);
if (property) {
@ -15108,7 +15109,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
type.propertyCacheWithoutObjectFunctionPropertyAugment ||= createSymbolTable() :
type.propertyCache ||= createSymbolTable();
properties.set(name, property);
if (skipObjectFunctionPropertyAugment && !type.propertyCache?.get(name)) {
// Propagate an entry from the non-augmented cache to the augmented cache unless the property is partial.
if (skipObjectFunctionPropertyAugment && !(getCheckFlags(property) & CheckFlags.Partial) && !type.propertyCache?.get(name)) {
const properties = type.propertyCache ||= createSymbolTable();
properties.set(name, property);
}

View File

@ -4,7 +4,7 @@
Assignability cache: 2,200 / 2,200 (nearest 100)
Type Count: 7,800 / 7,800 (nearest 100)
Instantiation count: 90,000 / 90,000 (nearest 500)
Symbol count: 66,500 / 66,500 (nearest 500)
Symbol count: 67,000 / 67,000 (nearest 500)
=== checkJsxChildrenCanBeTupleType.tsx ===
/// <reference path="react16.d.ts" />

View File

@ -4,7 +4,7 @@
Assignability cache: 200 / 200 (nearest 100)
Type Count: 1,000 / 1,000 (nearest 100)
Instantiation count: 2,500 / 2,500 (nearest 500)
Symbol count: 25,500 / 26,000 (nearest 500)
Symbol count: 25,500 / 25,500 (nearest 500)
=== infiniteConstraints.ts ===
// Both of the following types trigger the recursion limiter in getImmediateBaseConstraint

View File

@ -3,7 +3,7 @@
=== Performance Stats ===
Identity cache: 200 / 200 (nearest 100)
Assignability cache: 13,300 / 13,500 (nearest 100)
Type Count: 27,300 / 27,600 (nearest 100)
Type Count: 27,200 / 27,600 (nearest 100)
Instantiation count: 374,500 / 375,500 (nearest 500)
Symbol count: 92,000 / 92,000 (nearest 500)

View File

@ -4,7 +4,7 @@
Assignability cache: 2,200 / 2,300 (nearest 100)
Type Count: 6,900 / 7,000 (nearest 100)
Instantiation count: 73,000 / 73,500 (nearest 500)
Symbol count: 70,500 / 70,500 (nearest 500)
Symbol count: 70,500 / 71,000 (nearest 500)
=== test.tsx ===
/// <reference path="react16.d.ts" />

View File

@ -0,0 +1,45 @@
/// <reference path="fourslash.ts" />
// @strict: true
// @lib: esnext
//// interface ComponentOptions<Props> {
//// setup?: (props: Props) => void;
//// name?: string;
//// }
////
//// interface FunctionalComponent<P> {
//// (props: P): void;
//// }
////
//// type ConcreteComponent<Props> =
//// | ComponentOptions<Props>
//// | FunctionalComponent<Props>;
////
//// type Component<Props = {}> = ConcreteComponent<Props>;
////
//// type WithInstallPlugin = { _prefix?: string };
////
////
//// /**/
//// export function withInstall<C extends Component, T extends WithInstallPlugin>(
//// component: C | C[],
//// target?: T,
//// ): string {
//// const componentWithInstall = (target ?? component) as T;
//// const components = Array.isArray(component) ? component : [component];
////
//// const { name } = components[0];
//// if (name) {
//// return name;
//// }
////
//// return "";
//// }
verify.noErrors();
goTo.marker();
edit.insert("type C = Component['name']");
verify.noErrors();