From 0f2dabcd4b7981f1cc8fe6c7d8079ca79a9a0cd7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 17 Apr 2021 04:07:46 -1000 Subject: [PATCH] Don't re-alias top-level type aliases with local type aliases (#43701) * No re-aliasing of top-level type aliases with local type aliases * Accept new baselines --- src/compiler/checker.ts | 12 +++++++++++- .../baselines/reference/conditionalTypes1.errors.txt | 4 ++-- tests/baselines/reference/conditionalTypes1.types | 10 +++++----- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7ed212ccb8b..dfc0e5bb5cb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12834,12 +12834,22 @@ namespace ts { typeParameters.length); return errorType; } + // We refrain from associating a local type alias with an instantiation of a top-level type alias + // because the local alias may end up being referenced in an inferred return type where it is not + // accessible--which in turn may lead to a large structural expansion of the type when generating + // a .d.ts file. See #43622 for an example. const aliasSymbol = getAliasSymbolForTypeNode(node); - return getTypeAliasInstantiation(symbol, typeArgumentsFromTypeReferenceNode(node), aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol)); + const newAliasSymbol = aliasSymbol && (isLocalTypeAlias(symbol) || !isLocalTypeAlias(aliasSymbol)) ? aliasSymbol : undefined; + return getTypeAliasInstantiation(symbol, typeArgumentsFromTypeReferenceNode(node), newAliasSymbol, getTypeArgumentsForAliasSymbol(newAliasSymbol)); } return checkNoTypeArguments(node, symbol) ? type : errorType; } + function isLocalTypeAlias(symbol: Symbol) { + const declaration = symbol.declarations?.find(isTypeAlias); + return !!(declaration && getContainingFunction(declaration)); + } + function getTypeReferenceName(node: TypeReferenceType): EntityNameOrEntityNameExpression | undefined { switch (node.kind) { case SyntaxKind.TypeReference: diff --git a/tests/baselines/reference/conditionalTypes1.errors.txt b/tests/baselines/reference/conditionalTypes1.errors.txt index 810520c7103..85f50cb0e7d 100644 --- a/tests/baselines/reference/conditionalTypes1.errors.txt +++ b/tests/baselines/reference/conditionalTypes1.errors.txt @@ -50,7 +50,7 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(159,5): error TS2 tests/cases/conformance/types/conditional/conditionalTypes1.ts(160,5): error TS2322: Type 'T' is not assignable to type 'ZeroOf'. Type 'string | number' is not assignable to type 'ZeroOf'. Type 'string' is not assignable to type 'ZeroOf'. -tests/cases/conformance/types/conditional/conditionalTypes1.ts(263,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'z' must be of type 'T1', but here has type 'T2'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(263,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'z' must be of type 'T1', but here has type 'Foo'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS2322: Type 'T95' is not assignable to type 'T94'. Type 'number | boolean' is not assignable to type 'T94'. Type 'number' is not assignable to type 'T94'. @@ -392,7 +392,7 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS var z: T1; var z: T2; // Error, T2 is distributive, T1 isn't ~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'z' must be of type 'T1', but here has type 'T2'. +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'z' must be of type 'T1', but here has type 'Foo'. !!! related TS6203 tests/cases/conformance/types/conditional/conditionalTypes1.ts:262:9: 'z' was also declared here. } diff --git a/tests/baselines/reference/conditionalTypes1.types b/tests/baselines/reference/conditionalTypes1.types index e360b3dd7f3..d655e3d6b04 100644 --- a/tests/baselines/reference/conditionalTypes1.types +++ b/tests/baselines/reference/conditionalTypes1.types @@ -816,7 +816,7 @@ function f32() { >T1 : T & U extends string ? boolean : number type T2 = Foo; ->T2 : T & U extends string ? boolean : number +>T2 : Foo var z: T1; >z : T & U extends string ? boolean : number @@ -829,16 +829,16 @@ function f33() { >f33 : () => void type T1 = Foo; ->T1 : T & U extends string ? boolean : number +>T1 : Foo type T2 = Bar; ->T2 : T & U extends string ? boolean : number +>T2 : Bar var z: T1; ->z : T & U extends string ? boolean : number +>z : Foo var z: T2; ->z : T & U extends string ? boolean : number +>z : Foo } // Repro from #21823