@@ -2377,7 +2377,7 @@ namespace ts {
23772377 return links.target;
23782378 }
23792379
2380- function markExportAsReferenced(node: ImportEqualsDeclaration | ExportAssignment | ExportSpecifier) {
2380+ function markExportAsReferenced(node: ImportEqualsDeclaration | ExportSpecifier) {
23812381 const symbol = getSymbolOfNode(node);
23822382 const target = resolveAlias(symbol);
23832383 if (target) {
@@ -2399,15 +2399,10 @@ namespace ts {
23992399 links.referenced = true;
24002400 const node = getDeclarationOfAliasSymbol(symbol);
24012401 if (!node) return Debug.fail();
2402- if (node.kind === SyntaxKind.ExportAssignment) {
2403- // export default <symbol>
2404- checkExpressionCached((<ExportAssignment>node).expression);
2405- }
2406- else if (node.kind === SyntaxKind.ExportSpecifier) {
2407- // export { <symbol> } or export { <symbol> as foo }
2408- checkExpressionCached((<ExportSpecifier>node).propertyName || (<ExportSpecifier>node).name);
2409- }
2410- else if (isInternalModuleImportEqualsDeclaration(node)) {
2402+ // We defer checking of the reference of an `import =` until the import itself is referenced,
2403+ // This way a chain of imports can be elided if ultimately the final input is only used in a type
2404+ // position.
2405+ if (isInternalModuleImportEqualsDeclaration(node)) {
24112406 // import foo = <symbol>
24122407 checkExpressionCached(<Expression>node.moduleReference);
24132408 }
@@ -17829,8 +17824,12 @@ namespace ts {
1782917824 return type;
1783017825 }
1783117826
17827+ function isExportOrExportExpression(location: Node) {
17828+ return !!findAncestor(location, e => e.parent && isExportAssignment(e.parent) && e.parent.expression === e && isEntityNameExpression(e));
17829+ }
17830+
1783217831 function markAliasReferenced(symbol: Symbol, location: Node) {
17833- if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !isInTypeQuery(location) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol))) {
17832+ if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !isInTypeQuery(location) && ((compilerOptions.preserveConstEnums && isExportOrExportExpression(location)) || !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol) ))) {
1783417833 markAliasSymbolAsReferenced(symbol);
1783517834 }
1783617835 }
@@ -18812,6 +18811,17 @@ namespace ts {
1881218811 return false;
1881318812 }
1881418813
18814+ function getContextualIterationType(kind: IterationTypeKind, functionDecl: SignatureDeclaration): Type | undefined {
18815+ const isAsync = !!(getFunctionFlags(functionDecl) & FunctionFlags.Async);
18816+ const contextualReturnType = getContextualReturnType(functionDecl);
18817+ if (contextualReturnType) {
18818+ return getIterationTypeOfGeneratorFunctionReturnType(kind, contextualReturnType, isAsync)
18819+ || undefined;
18820+ }
18821+
18822+ return undefined;
18823+ }
18824+
1881518825 function getContextualReturnType(functionDecl: SignatureDeclaration): Type | undefined {
1881618826 // If the containing function has a return type annotation, is a constructor, or is a get accessor whose
1881718827 // corresponding set accessor has a type annotation, return statements in the function are contextually typed
@@ -20341,8 +20351,8 @@ namespace ts {
2034120351 // if jsx emit was not react as there wont be error being emitted
2034220352 reactSym.isReferenced = SymbolFlags.All;
2034320353
20344- // If react symbol is alias, mark it as referenced
20345- if (reactSym.flags & SymbolFlags.Alias && !isConstEnumOrConstEnumOnlyModule(resolveAlias(reactSym)) ) {
20354+ // If react symbol is alias, mark it as refereced
20355+ if (reactSym.flags & SymbolFlags.Alias) {
2034620356 markAliasSymbolAsReferenced(reactSym);
2034720357 }
2034820358 }
@@ -23477,7 +23487,11 @@ namespace ts {
2347723487 }
2347823488
2347923489 if (isGenerator) {
23480- return createGeneratorReturnType(yieldType || neverType, returnType || fallbackReturnType, nextType || unknownType, isAsync);
23490+ return createGeneratorReturnType(
23491+ yieldType || neverType,
23492+ returnType || fallbackReturnType,
23493+ nextType || getContextualIterationType(IterationTypeKind.Next, func) || unknownType,
23494+ isAsync);
2348123495 }
2348223496 else {
2348323497 // From within an async function you can return either a non-promise value or a promise. Any
@@ -24839,13 +24853,7 @@ namespace ts {
2483924853 || anyType;
2484024854 }
2484124855
24842- const contextualReturnType = getContextualReturnType(func);
24843- if (contextualReturnType) {
24844- return getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Next, contextualReturnType, isAsync)
24845- || anyType;
24846- }
24847-
24848- return anyType;
24856+ return getContextualIterationType(IterationTypeKind.Next, func) || anyType;
2484924857 }
2485024858
2485124859 function checkConditionalExpression(node: ConditionalExpression, checkMode?: CheckMode): Type {
@@ -24894,7 +24902,7 @@ namespace ts {
2489424902 return result;
2489524903 }
2489624904
24897- function checkExpressionCached(node: Expression, checkMode?: CheckMode): Type {
24905+ function checkExpressionCached(node: Expression | QualifiedName , checkMode?: CheckMode): Type {
2489824906 const links = getNodeLinks(node);
2489924907 if (!links.resolvedType) {
2490024908 if (checkMode && checkMode !== CheckMode.Normal) {
@@ -25222,7 +25230,8 @@ namespace ts {
2522225230 (node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).expression === node) ||
2522325231 (node.parent.kind === SyntaxKind.ElementAccessExpression && (<ElementAccessExpression>node.parent).expression === node) ||
2522425232 ((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(<Identifier>node) ||
25225- (node.parent.kind === SyntaxKind.TypeQuery && (<TypeQueryNode>node.parent).exprName === node));
25233+ (node.parent.kind === SyntaxKind.TypeQuery && (<TypeQueryNode>node.parent).exprName === node)) ||
25234+ (node.parent.kind === SyntaxKind.ExportSpecifier && (compilerOptions.preserveConstEnums || node.flags & NodeFlags.Ambient)); // We allow reexporting const enums
2522625235
2522725236 if (!ok) {
2522825237 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);
@@ -30152,6 +30161,10 @@ namespace ts {
3015230161 }
3015330162 else {
3015430163 markExportAsReferenced(node);
30164+ const target = symbol && (symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol);
30165+ if (!target || target === unknownSymbol || target.flags & SymbolFlags.Value) {
30166+ checkExpressionCached(node.propertyName || node.name);
30167+ }
3015530168 }
3015630169 }
3015730170 }
@@ -30178,7 +30191,17 @@ namespace ts {
3017830191 grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers);
3017930192 }
3018030193 if (node.expression.kind === SyntaxKind.Identifier) {
30181- markExportAsReferenced(node);
30194+ const id = node.expression as Identifier;
30195+ const sym = resolveEntityName(id, SymbolFlags.All, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, node);
30196+ if (sym) {
30197+ markAliasReferenced(sym, id);
30198+ // If not a value, we're interpreting the identifier as a type export, along the lines of (`export { Id as default }`)
30199+ const target = sym.flags & SymbolFlags.Alias ? resolveAlias(sym) : sym;
30200+ if (target === unknownSymbol || target.flags & SymbolFlags.Value) {
30201+ // However if it is a value, we need to check it's being used correctly
30202+ checkExpressionCached(node.expression);
30203+ }
30204+ }
3018230205
3018330206 if (getEmitDeclarations(compilerOptions)) {
3018430207 collectLinkedAliases(node.expression as Identifier, /*setVisibility*/ true);
0 commit comments