From 8c9128ada31cc3a5b3378738bc19690a77f4fb84 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 13 Apr 2020 14:42:08 -0700 Subject: [PATCH 1/4] Add tests --- .../namedImportNonExistentName.errors.txt | 16 +++++++++++++ .../reference/namedImportNonExistentName.js | 19 +++++++++++++++ .../namedImportNonExistentName.symbols | 23 ++++++++++++++++++ .../namedImportNonExistentName.types | 24 +++++++++++++++++++ ...eAugmentationWithNonExistentNamedImport.ts | 16 +++++++++++++ .../compiler/namedImportNonExistentName.ts | 11 +++++++++ 6 files changed, 109 insertions(+) create mode 100644 tests/baselines/reference/namedImportNonExistentName.errors.txt create mode 100644 tests/baselines/reference/namedImportNonExistentName.js create mode 100644 tests/baselines/reference/namedImportNonExistentName.symbols create mode 100644 tests/baselines/reference/namedImportNonExistentName.types create mode 100644 tests/cases/compiler/moduleAugmentationWithNonExistentNamedImport.ts create mode 100644 tests/cases/compiler/namedImportNonExistentName.ts diff --git a/tests/baselines/reference/namedImportNonExistentName.errors.txt b/tests/baselines/reference/namedImportNonExistentName.errors.txt new file mode 100644 index 0000000000000..2d1295ec76460 --- /dev/null +++ b/tests/baselines/reference/namedImportNonExistentName.errors.txt @@ -0,0 +1,16 @@ +tests/cases/compiler/bar.ts(1,10): error TS2305: Module '"./foo"' has no exported member 'Bar'. + + +==== tests/cases/compiler/foo.d.ts (0 errors) ==== + export = Foo; + export as namespace Foo; + + declare namespace Foo { + function foo(); + } + +==== tests/cases/compiler/bar.ts (1 errors) ==== + import { Bar, toString, foo } from './foo'; + ~~~ +!!! error TS2305: Module '"./foo"' has no exported member 'Bar'. + foo(); \ No newline at end of file diff --git a/tests/baselines/reference/namedImportNonExistentName.js b/tests/baselines/reference/namedImportNonExistentName.js new file mode 100644 index 0000000000000..c93d3af1bdfa1 --- /dev/null +++ b/tests/baselines/reference/namedImportNonExistentName.js @@ -0,0 +1,19 @@ +//// [tests/cases/compiler/namedImportNonExistentName.ts] //// + +//// [foo.d.ts] +export = Foo; +export as namespace Foo; + +declare namespace Foo { + function foo(); +} + +//// [bar.ts] +import { Bar, toString, foo } from './foo'; +foo(); + +//// [bar.js] +"use strict"; +exports.__esModule = true; +var foo_1 = require("./foo"); +foo_1.foo(); diff --git a/tests/baselines/reference/namedImportNonExistentName.symbols b/tests/baselines/reference/namedImportNonExistentName.symbols new file mode 100644 index 0000000000000..7a2ec886b4db3 --- /dev/null +++ b/tests/baselines/reference/namedImportNonExistentName.symbols @@ -0,0 +1,23 @@ +=== tests/cases/compiler/foo.d.ts === +export = Foo; +>Foo : Symbol(Foo, Decl(foo.d.ts, 1, 24)) + +export as namespace Foo; +>Foo : Symbol(Foo, Decl(foo.d.ts, 0, 13)) + +declare namespace Foo { +>Foo : Symbol(Foo, Decl(foo.d.ts, 1, 24)) + + function foo(); +>foo : Symbol(foo, Decl(foo.d.ts, 3, 23)) +} + +=== tests/cases/compiler/bar.ts === +import { Bar, toString, foo } from './foo'; +>Bar : Symbol(Bar, Decl(bar.ts, 0, 8)) +>toString : Symbol(toString, Decl(bar.ts, 0, 13)) +>foo : Symbol(foo, Decl(bar.ts, 0, 23)) + +foo(); +>foo : Symbol(foo, Decl(bar.ts, 0, 23)) + diff --git a/tests/baselines/reference/namedImportNonExistentName.types b/tests/baselines/reference/namedImportNonExistentName.types new file mode 100644 index 0000000000000..6ac0f756a0b5a --- /dev/null +++ b/tests/baselines/reference/namedImportNonExistentName.types @@ -0,0 +1,24 @@ +=== tests/cases/compiler/foo.d.ts === +export = Foo; +>Foo : typeof Foo + +export as namespace Foo; +>Foo : typeof Foo + +declare namespace Foo { +>Foo : typeof Foo + + function foo(); +>foo : () => any +} + +=== tests/cases/compiler/bar.ts === +import { Bar, toString, foo } from './foo'; +>Bar : any +>toString : () => string +>foo : () => any + +foo(); +>foo() : any +>foo : () => any + diff --git a/tests/cases/compiler/moduleAugmentationWithNonExistentNamedImport.ts b/tests/cases/compiler/moduleAugmentationWithNonExistentNamedImport.ts new file mode 100644 index 0000000000000..6741e58cc91d6 --- /dev/null +++ b/tests/cases/compiler/moduleAugmentationWithNonExistentNamedImport.ts @@ -0,0 +1,16 @@ +// @filename: foo.d.ts +export = Foo; +export as namespace Foo; + +declare namespace Foo { + function foo(); +} + +declare global { + namespace Bar { } +} + +// @filename: bar.d.ts +import { Bar } from './foo'; +export = Bar; +export as namespace Bar; \ No newline at end of file diff --git a/tests/cases/compiler/namedImportNonExistentName.ts b/tests/cases/compiler/namedImportNonExistentName.ts new file mode 100644 index 0000000000000..473a70395a831 --- /dev/null +++ b/tests/cases/compiler/namedImportNonExistentName.ts @@ -0,0 +1,11 @@ +// @filename: foo.d.ts +export = Foo; +export as namespace Foo; + +declare namespace Foo { + function foo(); +} + +// @filename: bar.ts +import { Bar, toString, foo } from './foo'; +foo(); \ No newline at end of file From 5af482c33b64b996e4d59f3b49f7c3b5fdb575a3 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 14 Apr 2020 11:26:06 -0700 Subject: [PATCH 2/4] Dont look at object or function type when looking for members of `export=` type to be resolved by named imports Fixes #37165 --- src/compiler/checker.ts | 22 +++++++------ ...ationWithNonExistentNamedImport.errors.txt | 21 +++++++++++++ ...entationWithNonExistentNamedImport.symbols | 31 +++++++++++++++++++ ...gmentationWithNonExistentNamedImport.types | 30 ++++++++++++++++++ .../namedImportNonExistentName.errors.txt | 25 +++++++++++++-- .../reference/namedImportNonExistentName.js | 14 ++++++++- .../namedImportNonExistentName.symbols | 21 +++++++++++++ .../namedImportNonExistentName.types | 24 +++++++++++++- .../compiler/namedImportNonExistentName.ts | 8 ++++- 9 files changed, 181 insertions(+), 15 deletions(-) create mode 100644 tests/baselines/reference/moduleAugmentationWithNonExistentNamedImport.errors.txt create mode 100644 tests/baselines/reference/moduleAugmentationWithNonExistentNamedImport.symbols create mode 100644 tests/baselines/reference/moduleAugmentationWithNonExistentNamedImport.types diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 52a667a14514f..e263889a1db5f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2586,7 +2586,7 @@ namespace ts { let symbolFromVariable: Symbol | undefined; // First check if module was specified with "export=". If so, get the member from the resolved type if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get(InternalSymbolName.ExportEquals)) { - symbolFromVariable = getPropertyOfType(getTypeOfSymbol(targetSymbol), name.escapedText); + symbolFromVariable = getPropertyOfType(getTypeOfSymbol(targetSymbol), name.escapedText, /*skipObjectFunctionPropertyAugment*/ true); } else { symbolFromVariable = getPropertyOfVariable(targetSymbol, name.escapedText); @@ -10432,7 +10432,7 @@ namespace ts { t; } - function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol | undefined { + function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String, skipObjectFunctionPropertyAugment?: boolean): Symbol | undefined { const propSet = createMap(); let indexTypes: Type[] | undefined; const isUnion = containingType.flags & TypeFlags.Union; @@ -10444,7 +10444,7 @@ namespace ts { for (const current of containingType.types) { const type = getApparentType(current); if (!(type === errorType || type.flags & TypeFlags.Never)) { - const prop = getPropertyOfType(type, name); + const prop = getPropertyOfType(type, name, skipObjectFunctionPropertyAugment); const modifiers = prop ? getDeclarationModifierFlagsFromSymbol(prop) : 0; if (prop && !(modifiers & excludeModifiers)) { if (isUnion) { @@ -10550,20 +10550,21 @@ namespace ts { // constituents, in which case the isPartial flag is set when the containing type is union type. We need // 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): Symbol | undefined { + function getUnionOrIntersectionProperty(type: UnionOrIntersectionType, name: __String, skipObjectFunctionPropertyAugment?: boolean): Symbol | undefined { const properties = type.propertyCache || (type.propertyCache = createSymbolTable()); let property = properties.get(name); if (!property) { - property = createUnionOrIntersectionProperty(type, name); - if (property) { + property = createUnionOrIntersectionProperty(type, name, skipObjectFunctionPropertyAugment); + // Dont set the result since it might not be correct if skipping lookup from property of Object and function type + if (property && !skipObjectFunctionPropertyAugment) { properties.set(name, property); } } return property; } - function getPropertyOfUnionOrIntersectionType(type: UnionOrIntersectionType, name: __String): Symbol | undefined { - const property = getUnionOrIntersectionProperty(type, name); + function getPropertyOfUnionOrIntersectionType(type: UnionOrIntersectionType, name: __String, skipObjectFunctionPropertyAugment?: boolean): Symbol | undefined { + const property = getUnionOrIntersectionProperty(type, name, skipObjectFunctionPropertyAugment); // We need to filter out partial properties in union types return property && !(getCheckFlags(property) & CheckFlags.ReadPartial) ? property : undefined; } @@ -10641,7 +10642,7 @@ namespace ts { * @param type a type to look up property from * @param name a name of property to look up in a given type */ - function getPropertyOfType(type: Type, name: __String): Symbol | undefined { + function getPropertyOfType(type: Type, name: __String, skipObjectFunctionPropertyAugment?: boolean): Symbol | undefined { type = getApparentType(getReducedType(type)); if (type.flags & TypeFlags.Object) { const resolved = resolveStructuredTypeMembers(type); @@ -10649,6 +10650,7 @@ namespace ts { if (symbol && symbolIsValue(symbol)) { return symbol; } + if (skipObjectFunctionPropertyAugment) return undefined; const functionType = resolved === anyFunctionType ? globalFunctionType : resolved.callSignatures.length ? globalCallableFunctionType : resolved.constructSignatures.length ? globalNewableFunctionType : @@ -10662,7 +10664,7 @@ namespace ts { return getPropertyOfObjectType(globalObjectType, name); } if (type.flags & TypeFlags.UnionOrIntersection) { - return getPropertyOfUnionOrIntersectionType(type, name); + return getPropertyOfUnionOrIntersectionType(type, name, skipObjectFunctionPropertyAugment); } return undefined; } diff --git a/tests/baselines/reference/moduleAugmentationWithNonExistentNamedImport.errors.txt b/tests/baselines/reference/moduleAugmentationWithNonExistentNamedImport.errors.txt new file mode 100644 index 0000000000000..8e4ef61316609 --- /dev/null +++ b/tests/baselines/reference/moduleAugmentationWithNonExistentNamedImport.errors.txt @@ -0,0 +1,21 @@ +tests/cases/compiler/bar.d.ts(1,10): error TS2305: Module '"./foo"' has no exported member 'Bar'. + + +==== tests/cases/compiler/foo.d.ts (0 errors) ==== + export = Foo; + export as namespace Foo; + + declare namespace Foo { + function foo(); + } + + declare global { + namespace Bar { } + } + +==== tests/cases/compiler/bar.d.ts (1 errors) ==== + import { Bar } from './foo'; + ~~~ +!!! error TS2305: Module '"./foo"' has no exported member 'Bar'. + export = Bar; + export as namespace Bar; \ No newline at end of file diff --git a/tests/baselines/reference/moduleAugmentationWithNonExistentNamedImport.symbols b/tests/baselines/reference/moduleAugmentationWithNonExistentNamedImport.symbols new file mode 100644 index 0000000000000..8e87803396bc6 --- /dev/null +++ b/tests/baselines/reference/moduleAugmentationWithNonExistentNamedImport.symbols @@ -0,0 +1,31 @@ +=== tests/cases/compiler/foo.d.ts === +export = Foo; +>Foo : Symbol(Foo, Decl(foo.d.ts, 1, 24)) + +export as namespace Foo; +>Foo : Symbol(Foo, Decl(foo.d.ts, 0, 13)) + +declare namespace Foo { +>Foo : Symbol(Foo, Decl(foo.d.ts, 1, 24)) + + function foo(); +>foo : Symbol(foo, Decl(foo.d.ts, 3, 23)) +} + +declare global { +>global : Symbol(global, Decl(foo.d.ts, 5, 1)) + + namespace Bar { } +>Bar : Symbol(Bar, Decl(foo.d.ts, 7, 16)) +} + +=== tests/cases/compiler/bar.d.ts === +import { Bar } from './foo'; +>Bar : Symbol(Bar, Decl(bar.d.ts, 0, 8)) + +export = Bar; +>Bar : Symbol(Bar, Decl(bar.d.ts, 0, 8)) + +export as namespace Bar; +>Bar : Symbol(Bar, Decl(bar.d.ts, 1, 13)) + diff --git a/tests/baselines/reference/moduleAugmentationWithNonExistentNamedImport.types b/tests/baselines/reference/moduleAugmentationWithNonExistentNamedImport.types new file mode 100644 index 0000000000000..99277395c85be --- /dev/null +++ b/tests/baselines/reference/moduleAugmentationWithNonExistentNamedImport.types @@ -0,0 +1,30 @@ +=== tests/cases/compiler/foo.d.ts === +export = Foo; +>Foo : typeof Foo + +export as namespace Foo; +>Foo : typeof Foo + +declare namespace Foo { +>Foo : typeof Foo + + function foo(); +>foo : () => any +} + +declare global { +>global : any + + namespace Bar { } +} + +=== tests/cases/compiler/bar.d.ts === +import { Bar } from './foo'; +>Bar : any + +export = Bar; +>Bar : any + +export as namespace Bar; +>Bar : any + diff --git a/tests/baselines/reference/namedImportNonExistentName.errors.txt b/tests/baselines/reference/namedImportNonExistentName.errors.txt index 2d1295ec76460..f26d48b64848e 100644 --- a/tests/baselines/reference/namedImportNonExistentName.errors.txt +++ b/tests/baselines/reference/namedImportNonExistentName.errors.txt @@ -1,4 +1,9 @@ tests/cases/compiler/bar.ts(1,10): error TS2305: Module '"./foo"' has no exported member 'Bar'. +tests/cases/compiler/bar.ts(1,15): error TS2305: Module '"./foo"' has no exported member 'toString'. +tests/cases/compiler/bar.ts(3,10): error TS2305: Module '"./foo2"' has no exported member 'a'. +tests/cases/compiler/bar.ts(3,13): error TS2305: Module '"./foo2"' has no exported member 'b'. +tests/cases/compiler/bar.ts(3,19): error TS2305: Module '"./foo2"' has no exported member 'd'. +tests/cases/compiler/bar.ts(3,22): error TS2305: Module '"./foo2"' has no exported member 'toString'. ==== tests/cases/compiler/foo.d.ts (0 errors) ==== @@ -9,8 +14,24 @@ tests/cases/compiler/bar.ts(1,10): error TS2305: Module '"./foo"' has no exporte function foo(); } -==== tests/cases/compiler/bar.ts (1 errors) ==== +==== tests/cases/compiler/foo2.ts (0 errors) ==== + let x: { a: string; c: string; } | { b: number; c: number; }; + export = x + +==== tests/cases/compiler/bar.ts (6 errors) ==== import { Bar, toString, foo } from './foo'; ~~~ !!! error TS2305: Module '"./foo"' has no exported member 'Bar'. - foo(); \ No newline at end of file + ~~~~~~~~ +!!! error TS2305: Module '"./foo"' has no exported member 'toString'. + foo(); + import { a, b, c, d, toString as foo2String } from './foo2'; + ~ +!!! error TS2305: Module '"./foo2"' has no exported member 'a'. + ~ +!!! error TS2305: Module '"./foo2"' has no exported member 'b'. + ~ +!!! error TS2305: Module '"./foo2"' has no exported member 'd'. + ~~~~~~~~ +!!! error TS2305: Module '"./foo2"' has no exported member 'toString'. + c; \ No newline at end of file diff --git a/tests/baselines/reference/namedImportNonExistentName.js b/tests/baselines/reference/namedImportNonExistentName.js index c93d3af1bdfa1..b017d9b3f093f 100644 --- a/tests/baselines/reference/namedImportNonExistentName.js +++ b/tests/baselines/reference/namedImportNonExistentName.js @@ -8,12 +8,24 @@ declare namespace Foo { function foo(); } +//// [foo2.ts] +let x: { a: string; c: string; } | { b: number; c: number; }; +export = x + //// [bar.ts] import { Bar, toString, foo } from './foo'; -foo(); +foo(); +import { a, b, c, d, toString as foo2String } from './foo2'; +c; +//// [foo2.js] +"use strict"; +var x; +module.exports = x; //// [bar.js] "use strict"; exports.__esModule = true; var foo_1 = require("./foo"); foo_1.foo(); +var foo2_1 = require("./foo2"); +foo2_1.c; diff --git a/tests/baselines/reference/namedImportNonExistentName.symbols b/tests/baselines/reference/namedImportNonExistentName.symbols index 7a2ec886b4db3..b6ec6ebb14021 100644 --- a/tests/baselines/reference/namedImportNonExistentName.symbols +++ b/tests/baselines/reference/namedImportNonExistentName.symbols @@ -12,6 +12,17 @@ declare namespace Foo { >foo : Symbol(foo, Decl(foo.d.ts, 3, 23)) } +=== tests/cases/compiler/foo2.ts === +let x: { a: string; c: string; } | { b: number; c: number; }; +>x : Symbol(x, Decl(foo2.ts, 0, 3)) +>a : Symbol(a, Decl(foo2.ts, 0, 8)) +>c : Symbol(c, Decl(foo2.ts, 0, 19)) +>b : Symbol(b, Decl(foo2.ts, 0, 36)) +>c : Symbol(c, Decl(foo2.ts, 0, 47)) + +export = x +>x : Symbol(x, Decl(foo2.ts, 0, 3)) + === tests/cases/compiler/bar.ts === import { Bar, toString, foo } from './foo'; >Bar : Symbol(Bar, Decl(bar.ts, 0, 8)) @@ -21,3 +32,13 @@ import { Bar, toString, foo } from './foo'; foo(); >foo : Symbol(foo, Decl(bar.ts, 0, 23)) +import { a, b, c, d, toString as foo2String } from './foo2'; +>a : Symbol(a, Decl(bar.ts, 2, 8)) +>b : Symbol(b, Decl(bar.ts, 2, 11)) +>c : Symbol(c, Decl(bar.ts, 2, 14)) +>d : Symbol(d, Decl(bar.ts, 2, 17)) +>foo2String : Symbol(foo2String, Decl(bar.ts, 2, 20)) + +c; +>c : Symbol(c, Decl(bar.ts, 2, 14)) + diff --git a/tests/baselines/reference/namedImportNonExistentName.types b/tests/baselines/reference/namedImportNonExistentName.types index 6ac0f756a0b5a..02ffb609f5dd8 100644 --- a/tests/baselines/reference/namedImportNonExistentName.types +++ b/tests/baselines/reference/namedImportNonExistentName.types @@ -12,13 +12,35 @@ declare namespace Foo { >foo : () => any } +=== tests/cases/compiler/foo2.ts === +let x: { a: string; c: string; } | { b: number; c: number; }; +>x : { a: string; c: string; } | { b: number; c: number; } +>a : string +>c : string +>b : number +>c : number + +export = x +>x : { a: string; c: string; } | { b: number; c: number; } + === tests/cases/compiler/bar.ts === import { Bar, toString, foo } from './foo'; >Bar : any ->toString : () => string +>toString : any >foo : () => any foo(); >foo() : any >foo : () => any +import { a, b, c, d, toString as foo2String } from './foo2'; +>a : any +>b : any +>c : string | number +>d : any +>toString : any +>foo2String : any + +c; +>c : string | number + diff --git a/tests/cases/compiler/namedImportNonExistentName.ts b/tests/cases/compiler/namedImportNonExistentName.ts index 473a70395a831..3fd3c3011cc96 100644 --- a/tests/cases/compiler/namedImportNonExistentName.ts +++ b/tests/cases/compiler/namedImportNonExistentName.ts @@ -6,6 +6,12 @@ declare namespace Foo { function foo(); } +// @filename: foo2.ts +let x: { a: string; c: string; } | { b: number; c: number; }; +export = x + // @filename: bar.ts import { Bar, toString, foo } from './foo'; -foo(); \ No newline at end of file +foo(); +import { a, b, c, d, toString as foo2String } from './foo2'; +c; \ No newline at end of file From a252ef9908df0719675c0a3b88cc495a9e6bfacd Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 24 Jul 2020 17:06:14 -0700 Subject: [PATCH 3/4] Create separate cache when skipping function and object property augmentation --- src/compiler/checker.ts | 7 ++++--- src/compiler/types.ts | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 43fd775826e9e..c689db58b01a6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10997,12 +10997,13 @@ namespace ts { // 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 { - const properties = type.propertyCache || (type.propertyCache = createSymbolTable()); + const properties = skipObjectFunctionPropertyAugment ? + type.propertyCacheWithoutObjectFunctionPropertyAugment ||= createSymbolTable() : + type.propertyCache ||= createSymbolTable(); let property = properties.get(name); if (!property) { property = createUnionOrIntersectionProperty(type, name, skipObjectFunctionPropertyAugment); - // Dont set the result since it might not be correct if skipping lookup from property of Object and function type - if (property && !skipObjectFunctionPropertyAugment) { + if (property) { properties.set(name, property); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 7ab69edd538ea..ac3dddfa3d8a8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5140,7 +5140,9 @@ namespace ts { /* @internal */ objectFlags: ObjectFlags; /* @internal */ - propertyCache: SymbolTable; // Cache of resolved properties + propertyCache?: SymbolTable; // Cache of resolved properties + /* @internal */ + propertyCacheWithoutObjectFunctionPropertyAugment?: SymbolTable; // Cache of resolved properties that does not augment function or object type properties /* @internal */ resolvedProperties: Symbol[]; /* @internal */ From 5a964bd1e0df1a86293dfcdc810cbfc16c4242e2 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 21 Oct 2020 13:09:59 -0700 Subject: [PATCH 4/4] Lookup in both cache if not skipObjectFunctionPropertyAugment --- src/compiler/checker.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c689db58b01a6..6847784cb4d06 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10997,13 +10997,14 @@ namespace ts { // 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 { - const properties = skipObjectFunctionPropertyAugment ? - type.propertyCacheWithoutObjectFunctionPropertyAugment ||= createSymbolTable() : - type.propertyCache ||= createSymbolTable(); - let property = properties.get(name); + let property = type.propertyCacheWithoutObjectFunctionPropertyAugment?.get(name) || + !skipObjectFunctionPropertyAugment ? type.propertyCache?.get(name) : undefined; if (!property) { property = createUnionOrIntersectionProperty(type, name, skipObjectFunctionPropertyAugment); if (property) { + const properties = skipObjectFunctionPropertyAugment ? + type.propertyCacheWithoutObjectFunctionPropertyAugment ||= createSymbolTable() : + type.propertyCache ||= createSymbolTable(); properties.set(name, property); } }