@@ -2253,7 +2253,7 @@ namespace ts {
2253
2253
return links.target;
2254
2254
}
2255
2255
2256
- function markExportAsReferenced(node: ImportEqualsDeclaration | ExportAssignment | ExportSpecifier) {
2256
+ function markExportAsReferenced(node: ImportEqualsDeclaration | ExportSpecifier) {
2257
2257
const symbol = getSymbolOfNode(node);
2258
2258
const target = resolveAlias(symbol);
2259
2259
if (target) {
@@ -2275,15 +2275,10 @@ namespace ts {
2275
2275
links.referenced = true;
2276
2276
const node = getDeclarationOfAliasSymbol(symbol);
2277
2277
if (!node) return Debug.fail();
2278
- if (node.kind === SyntaxKind.ExportAssignment) {
2279
- // export default <symbol>
2280
- checkExpressionCached((<ExportAssignment>node).expression);
2281
- }
2282
- else if (node.kind === SyntaxKind.ExportSpecifier) {
2283
- // export { <symbol> } or export { <symbol> as foo }
2284
- checkExpressionCached((<ExportSpecifier>node).propertyName || (<ExportSpecifier>node).name);
2285
- }
2286
- else if (isInternalModuleImportEqualsDeclaration(node)) {
2278
+ // We defer checking of the reference of an `import =` until the import itself is referenced,
2279
+ // This way a chain of imports can be elided if ultimately the final input is only used in a type
2280
+ // position.
2281
+ if (isInternalModuleImportEqualsDeclaration(node)) {
2287
2282
// import foo = <symbol>
2288
2283
checkExpressionCached(<Expression>node.moduleReference);
2289
2284
}
@@ -17430,7 +17425,7 @@ namespace ts {
17430
17425
}
17431
17426
17432
17427
function markAliasReferenced(symbol: Symbol, location: Node) {
17433
- if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !isInTypeQuery(location) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol))) {
17428
+ if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !isInTypeQuery(location) && (compilerOptions.preserveConstEnums || !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol) ))) {
17434
17429
markAliasSymbolAsReferenced(symbol);
17435
17430
}
17436
17431
}
@@ -19941,8 +19936,8 @@ namespace ts {
19941
19936
// if jsx emit was not react as there wont be error being emitted
19942
19937
reactSym.isReferenced = SymbolFlags.All;
19943
19938
19944
- // If react symbol is alias, mark it as referenced
19945
- if (reactSym.flags & SymbolFlags.Alias && !isConstEnumOrConstEnumOnlyModule(resolveAlias(reactSym)) ) {
19939
+ // If react symbol is alias, mark it as refereced
19940
+ if (reactSym.flags & SymbolFlags.Alias) {
19946
19941
markAliasSymbolAsReferenced(reactSym);
19947
19942
}
19948
19943
}
@@ -24163,7 +24158,7 @@ namespace ts {
24163
24158
return result;
24164
24159
}
24165
24160
24166
- function checkExpressionCached(node: Expression, checkMode?: CheckMode): Type {
24161
+ function checkExpressionCached(node: Expression | QualifiedName , checkMode?: CheckMode): Type {
24167
24162
const links = getNodeLinks(node);
24168
24163
if (!links.resolvedType) {
24169
24164
if (checkMode && checkMode !== CheckMode.Normal) {
@@ -24471,7 +24466,8 @@ namespace ts {
24471
24466
(node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).expression === node) ||
24472
24467
(node.parent.kind === SyntaxKind.ElementAccessExpression && (<ElementAccessExpression>node.parent).expression === node) ||
24473
24468
((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(<Identifier>node) ||
24474
- (node.parent.kind === SyntaxKind.TypeQuery && (<TypeQueryNode>node.parent).exprName === node));
24469
+ (node.parent.kind === SyntaxKind.TypeQuery && (<TypeQueryNode>node.parent).exprName === node)) ||
24470
+ (node.parent.kind === SyntaxKind.ExportSpecifier); // We allow reexporting const enums
24475
24471
24476
24472
if (!ok) {
24477
24473
error(node, Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query);
@@ -29049,6 +29045,10 @@ namespace ts {
29049
29045
}
29050
29046
else {
29051
29047
markExportAsReferenced(node);
29048
+ const target = symbol && (symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol);
29049
+ if (!target || target === unknownSymbol || target.flags & SymbolFlags.Value) {
29050
+ checkExpressionCached(node.propertyName || node.name);
29051
+ }
29052
29052
}
29053
29053
}
29054
29054
}
@@ -29075,7 +29075,17 @@ namespace ts {
29075
29075
grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers);
29076
29076
}
29077
29077
if (node.expression.kind === SyntaxKind.Identifier) {
29078
- markExportAsReferenced(node);
29078
+ const id = node.expression as Identifier;
29079
+ const sym = resolveEntityName(id, SymbolFlags.All, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, node);
29080
+ if (sym) {
29081
+ markAliasReferenced(sym, id);
29082
+ // If not a value, we're interpreting the identifier as a type export, along the lines of (`export { Id as default }`)
29083
+ const target = sym.flags & SymbolFlags.Alias ? resolveAlias(sym) : sym;
29084
+ if (target === unknownSymbol || target.flags & SymbolFlags.Value) {
29085
+ // However if it is a value, we need to check it's being used correctly
29086
+ checkExpressionCached(node.expression);
29087
+ }
29088
+ }
29079
29089
29080
29090
if (getEmitDeclarations(compilerOptions)) {
29081
29091
collectLinkedAliases(node.expression as Identifier, /*setVisibility*/ true);
0 commit comments