@@ -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
}
@@ -17352,7 +17347,7 @@ namespace ts {
17352
17347
}
17353
17348
17354
17349
function markAliasReferenced(symbol: Symbol, location: Node) {
17355
- if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !isInTypeQuery(location) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol))) {
17350
+ if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !isInTypeQuery(location) && (compilerOptions.preserveConstEnums || !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol) ))) {
17356
17351
markAliasSymbolAsReferenced(symbol);
17357
17352
}
17358
17353
}
@@ -19848,8 +19843,8 @@ namespace ts {
19848
19843
// if jsx emit was not react as there wont be error being emitted
19849
19844
reactSym.isReferenced = SymbolFlags.All;
19850
19845
19851
- // If react symbol is alias, mark it as referenced
19852
- if (reactSym.flags & SymbolFlags.Alias && !isConstEnumOrConstEnumOnlyModule(resolveAlias(reactSym)) ) {
19846
+ // If react symbol is alias, mark it as refereced
19847
+ if (reactSym.flags & SymbolFlags.Alias) {
19853
19848
markAliasSymbolAsReferenced(reactSym);
19854
19849
}
19855
19850
}
@@ -24048,7 +24043,7 @@ namespace ts {
24048
24043
return result;
24049
24044
}
24050
24045
24051
- function checkExpressionCached(node: Expression, checkMode?: CheckMode): Type {
24046
+ function checkExpressionCached(node: Expression | QualifiedName , checkMode?: CheckMode): Type {
24052
24047
const links = getNodeLinks(node);
24053
24048
if (!links.resolvedType) {
24054
24049
if (checkMode && checkMode !== CheckMode.Normal) {
@@ -24356,7 +24351,8 @@ namespace ts {
24356
24351
(node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).expression === node) ||
24357
24352
(node.parent.kind === SyntaxKind.ElementAccessExpression && (<ElementAccessExpression>node.parent).expression === node) ||
24358
24353
((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(<Identifier>node) ||
24359
- (node.parent.kind === SyntaxKind.TypeQuery && (<TypeQueryNode>node.parent).exprName === node));
24354
+ (node.parent.kind === SyntaxKind.TypeQuery && (<TypeQueryNode>node.parent).exprName === node)) ||
24355
+ (node.parent.kind === SyntaxKind.ExportSpecifier); // We allow reexporting const enums
24360
24356
24361
24357
if (!ok) {
24362
24358
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);
@@ -28934,6 +28930,10 @@ namespace ts {
28934
28930
}
28935
28931
else {
28936
28932
markExportAsReferenced(node);
28933
+ const target = symbol && (symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol);
28934
+ if (!target || target === unknownSymbol || target.flags & SymbolFlags.Value) {
28935
+ checkExpressionCached(node.propertyName || node.name);
28936
+ }
28937
28937
}
28938
28938
}
28939
28939
}
@@ -28960,7 +28960,17 @@ namespace ts {
28960
28960
grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers);
28961
28961
}
28962
28962
if (node.expression.kind === SyntaxKind.Identifier) {
28963
- markExportAsReferenced(node);
28963
+ const id = node.expression as Identifier;
28964
+ const sym = resolveEntityName(id, SymbolFlags.All, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, node);
28965
+ if (sym) {
28966
+ markAliasReferenced(sym, id);
28967
+ // If not a value, we're interpreting the identifier as a type export, along the lines of (`export { Id as default }`)
28968
+ const target = sym.flags & SymbolFlags.Alias ? resolveAlias(sym) : sym;
28969
+ if (target === unknownSymbol || target.flags & SymbolFlags.Value) {
28970
+ // However if it is a value, we need to check it's being used correctly
28971
+ checkExpressionCached(node.expression);
28972
+ }
28973
+ }
28964
28974
28965
28975
if (getEmitDeclarations(compilerOptions)) {
28966
28976
collectLinkedAliases(node.expression as Identifier, /*setVisibility*/ true);
0 commit comments