From 892936f4a18ded0216ae1c805a9890ebb8572fe3 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Tue, 9 Apr 2024 12:10:17 -0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20Pick=20PR=20#58083=20(Don't=20pr?= =?UTF-8?q?opagate=20partial=20union/inter...)=20into=20release-5.4=20(#58?= =?UTF-8?q?136)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Anders Hejlsberg --- src/compiler/checker.ts | 8 ++-- ...ialUnionPropertyCacheInconsistentErrors.ts | 45 +++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/partialUnionPropertyCacheInconsistentErrors.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 175caa9eef16e..c3d194211c56a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14788,8 +14788,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) { @@ -14797,7 +14798,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); } diff --git a/tests/cases/fourslash/partialUnionPropertyCacheInconsistentErrors.ts b/tests/cases/fourslash/partialUnionPropertyCacheInconsistentErrors.ts new file mode 100644 index 0000000000000..7d793b520fa05 --- /dev/null +++ b/tests/cases/fourslash/partialUnionPropertyCacheInconsistentErrors.ts @@ -0,0 +1,45 @@ +/// + +// @strict: true +// @lib: esnext + +//// interface ComponentOptions { +//// setup?: (props: Props) => void; +//// name?: string; +//// } +//// +//// interface FunctionalComponent

{ +//// (props: P): void; +//// } +//// +//// type ConcreteComponent = +//// | ComponentOptions +//// | FunctionalComponent; +//// +//// type Component = ConcreteComponent; +//// +//// type WithInstallPlugin = { _prefix?: string }; +//// +//// +//// /**/ +//// export function withInstall( +//// 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(); \ No newline at end of file