Skip to content

Commit a3092c7

Browse files
authored
Preserve alias symbols on references to type aliases via imports (#51152)
* Preserve alias symbols on references to type aliases via imports * Fix lint
1 parent 00dc0b6 commit a3092c7

9 files changed

+696
-22
lines changed

src/compiler/checker.ts

+18-2
Original file line numberDiff line numberDiff line change
@@ -14888,8 +14888,24 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1488814888
// accessible--which in turn may lead to a large structural expansion of the type when generating
1488914889
// a .d.ts file. See #43622 for an example.
1489014890
const aliasSymbol = getAliasSymbolForTypeNode(node);
14891-
const newAliasSymbol = aliasSymbol && (isLocalTypeAlias(symbol) || !isLocalTypeAlias(aliasSymbol)) ? aliasSymbol : undefined;
14892-
return getTypeAliasInstantiation(symbol, typeArgumentsFromTypeReferenceNode(node), newAliasSymbol, getTypeArgumentsForAliasSymbol(newAliasSymbol));
14891+
let newAliasSymbol = aliasSymbol && (isLocalTypeAlias(symbol) || !isLocalTypeAlias(aliasSymbol)) ? aliasSymbol : undefined;
14892+
let aliasTypeArguments: Type[] | undefined;
14893+
if (newAliasSymbol) {
14894+
aliasTypeArguments = getTypeArgumentsForAliasSymbol(newAliasSymbol);
14895+
}
14896+
else if (isTypeReferenceType(node)) {
14897+
const aliasSymbol = resolveTypeReferenceName(node, SymbolFlags.Alias, /*ignoreErrors*/ true);
14898+
// refers to an alias import/export/reexport - by making sure we use the target as an aliasSymbol,
14899+
// we ensure the exported symbol is used to refer to the type when it's reserialized later
14900+
if (aliasSymbol && aliasSymbol !== unknownSymbol) {
14901+
const resolved = resolveAlias(aliasSymbol);
14902+
if (resolved && resolved.flags & SymbolFlags.TypeAlias) {
14903+
newAliasSymbol = resolved;
14904+
aliasTypeArguments = typeArgumentsFromTypeReferenceNode(node);
14905+
}
14906+
}
14907+
}
14908+
return getTypeAliasInstantiation(symbol, typeArgumentsFromTypeReferenceNode(node), newAliasSymbol, aliasTypeArguments);
1489314909
}
1489414910
return checkNoTypeArguments(node, symbol) ? type : errorType;
1489514911
}

tests/baselines/reference/declarationEmitExportAssignedNamespaceNoTripleSlashTypesReference.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ import { Component } from 'react';
8080
export declare function getComp(): Component;
8181
//// [inferred-comp-export.d.ts]
8282
export declare const obj: {
83-
comp: import("react").Component<any, {}, {}>;
83+
comp: import("react").Component;
8484
};
8585
//// [some-other-file.d.ts]
8686
export * from '@emotion/core';

tests/baselines/reference/declarationEmitExportAssignedNamespaceNoTripleSlashTypesReference.types

+7-7
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,24 @@ export function getComp(): Component {
3636
>getComp : () => Component
3737

3838
return {} as any as Component
39-
>{} as any as Component : Component<any, {}, {}>
39+
>{} as any as Component : Component
4040
>{} as any : any
4141
>{} : {}
4242
}
4343
=== tests/cases/compiler/src/inferred-comp-export.ts ===
4444
import { getComp } from "./get-comp";
45-
>getComp : () => import("tests/cases/compiler/node_modules/@types/react/index").Component<any, {}, {}>
45+
>getComp : () => import("tests/cases/compiler/node_modules/@types/react/index").Component
4646

4747
// this shouldn't need any triple-slash references - it should have a direct import to `react` and that's it
4848
// This issue (#35343) _only_ reproduces in the test harness when the file in question is in a subfolder
4949
export const obj = {
50-
>obj : { comp: import("tests/cases/compiler/node_modules/@types/react/index").Component<any, {}, {}>; }
51-
>{ comp: getComp()} : { comp: import("tests/cases/compiler/node_modules/@types/react/index").Component<any, {}, {}>; }
50+
>obj : { comp: import("tests/cases/compiler/node_modules/@types/react/index").Component; }
51+
>{ comp: getComp()} : { comp: import("tests/cases/compiler/node_modules/@types/react/index").Component; }
5252

5353
comp: getComp()
54-
>comp : import("tests/cases/compiler/node_modules/@types/react/index").Component<any, {}, {}>
55-
>getComp() : import("tests/cases/compiler/node_modules/@types/react/index").Component<any, {}, {}>
56-
>getComp : () => import("tests/cases/compiler/node_modules/@types/react/index").Component<any, {}, {}>
54+
>comp : import("tests/cases/compiler/node_modules/@types/react/index").Component
55+
>getComp() : import("tests/cases/compiler/node_modules/@types/react/index").Component
56+
>getComp : () => import("tests/cases/compiler/node_modules/@types/react/index").Component
5757
}
5858
=== tests/cases/compiler/src/some-other-file.ts ===
5959

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
//// [tests/cases/compiler/declarationEmitRecursiveConditionalAliasPreserved.ts] ////
2+
3+
//// [input.d.ts]
4+
type _BuildPowersOf2LengthArrays<
5+
Length extends number,
6+
AccumulatedArray extends never[][],
7+
> = AccumulatedArray[0][Length] extends never
8+
? AccumulatedArray
9+
: _BuildPowersOf2LengthArrays<
10+
Length,
11+
[[...AccumulatedArray[0], ...AccumulatedArray[0]], ...AccumulatedArray]
12+
>;
13+
14+
type _ConcatLargestUntilDone<
15+
Length extends number,
16+
AccumulatedArray extends never[][],
17+
NextArray extends never[],
18+
> = NextArray['length'] extends Length
19+
? NextArray
20+
: [...AccumulatedArray[0], ...NextArray][Length] extends never
21+
? _ConcatLargestUntilDone<
22+
Length,
23+
AccumulatedArray extends [AccumulatedArray[0], ...infer U]
24+
? U extends never[][]
25+
? U
26+
: never
27+
: never,
28+
NextArray
29+
>
30+
: _ConcatLargestUntilDone<
31+
Length,
32+
AccumulatedArray extends [AccumulatedArray[0], ...infer U]
33+
? U extends never[][]
34+
? U
35+
: never
36+
: never,
37+
[...AccumulatedArray[0], ...NextArray]
38+
>
39+
40+
type _Replace<R extends unknown[], T> = { [K in keyof R]: T };
41+
42+
export type TupleOf<Type, Length extends number> = number extends Length
43+
? Type[]
44+
: {
45+
// in case Length is a union
46+
[LengthKey in Length]: _BuildPowersOf2LengthArrays<
47+
LengthKey,
48+
[[never]]
49+
> extends infer TwoDimensionalArray
50+
? TwoDimensionalArray extends never[][]
51+
? _Replace<_ConcatLargestUntilDone<LengthKey, TwoDimensionalArray, []>, Type>
52+
: never
53+
: never
54+
}[Length];
55+
56+
export type Subtract<N1 extends number, N2 extends number> = TupleOf<never, N1> extends [
57+
...TupleOf<never, N2>,
58+
...infer R,
59+
]
60+
? R['length']
61+
: never;
62+
63+
export type Decrement<T extends number> = Subtract<T, 1>;
64+
65+
export type Add<N1 extends number, N2 extends number> = [
66+
...TupleOf<never, N1>,
67+
...TupleOf<never, N2>,
68+
]['length'] &
69+
// intersection to suppress compiler narrowing bug
70+
number;
71+
72+
type _MultiAdd<
73+
Num extends number,
74+
Accumulator extends number,
75+
IterationsLeft extends number,
76+
> = IterationsLeft extends 0
77+
? Accumulator
78+
: _MultiAdd<Num, Add<Num, Accumulator>, Decrement<IterationsLeft>>
79+
80+
export type Multiply<N1 extends number, N2 extends number> = number extends N1 | N2
81+
? number
82+
: {
83+
[K2 in N2]: { [K1 in N1]: _MultiAdd<K1, 0, N2> }[N1]
84+
}[N2]
85+
86+
type PowerTailRec<
87+
Num extends number,
88+
PowerOf extends number,
89+
Result extends number,
90+
> = number extends PowerOf
91+
? number
92+
: PowerOf extends 0
93+
? Result
94+
: PowerTailRec<Num, Decrement<PowerOf>, Multiply<Result, Num>>;
95+
96+
export type Power<Num extends number, PowerOf extends number> = PowerTailRec<Num, PowerOf, 1>;
97+
98+
//// [a.tsx]
99+
import { Power } from "./input";
100+
101+
export const power = <Num extends number, PowerOf extends number>(
102+
num: Num,
103+
powerOf: PowerOf
104+
): Power<Num, PowerOf> => (num ** powerOf) as never;
105+
106+
//// [a.js]
107+
"use strict";
108+
exports.__esModule = true;
109+
exports.power = void 0;
110+
var power = function (num, powerOf) { return (Math.pow(num, powerOf)); };
111+
exports.power = power;
112+
113+
114+
//// [a.d.ts]
115+
import { Power } from "./input";
116+
export declare const power: <Num extends number, PowerOf extends number>(num: Num, powerOf: PowerOf) => Power<Num, PowerOf>;

0 commit comments

Comments
 (0)