@@ -196,6 +196,7 @@ namespace ts {
196196 Source = 1 << 0,
197197 Target = 1 << 1,
198198 PropertyCheck = 1 << 2,
199+ InPropertyCheck = 1 << 3,
199200 }
200201
201202 const enum MappedTypeModifiers {
@@ -6132,7 +6133,8 @@ namespace ts {
61326133 // Each overload becomes a separate function declaration, in order
61336134 const decl = signatureToSignatureDeclarationHelper(sig, SyntaxKind.FunctionDeclaration, context, includePrivateSymbol, bundled) as FunctionDeclaration;
61346135 decl.name = createIdentifier(localName);
6135- addResult(setTextRange(decl, sig.declaration), modifierFlags);
6136+ // for expressions assigned to `var`s, use the `var` as the text range
6137+ addResult(setTextRange(decl, sig.declaration && isVariableDeclaration(sig.declaration.parent) && sig.declaration.parent.parent || sig.declaration), modifierFlags);
61366138 }
61376139 // Module symbol emit will take care of module-y members, provided it has exports
61386140 if (!(symbol.flags & (SymbolFlags.ValueModule | SymbolFlags.NamespaceModule) && !!symbol.exports && !!symbol.exports.size)) {
@@ -6210,14 +6212,18 @@ namespace ts {
62106212 ];
62116213 const symbolProps = getPropertiesOfType(classType);
62126214 const publicSymbolProps = filter(symbolProps, s => {
6215+ // `valueDeclaration` could be undefined if inherited from
6216+ // a union/intersection base type, but inherited properties
6217+ // don't matter here.
62136218 const valueDecl = s.valueDeclaration;
6214- Debug.assertIsDefined(valueDecl);
6215- return !(isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name));
6219+ return valueDecl && !(isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name));
62166220 });
62176221 const hasPrivateIdentifier = some(symbolProps, s => {
6222+ // `valueDeclaration` could be undefined if inherited from
6223+ // a union/intersection base type, but inherited properties
6224+ // don't matter here.
62186225 const valueDecl = s.valueDeclaration;
6219- Debug.assertIsDefined(valueDecl);
6220- return isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name);
6226+ return valueDecl && isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name);
62216227 });
62226228 // Boil down all private properties into a single one.
62236229 const privateProperties = hasPrivateIdentifier ?
@@ -10419,7 +10425,7 @@ namespace ts {
1041910425 if (!firstValueDeclaration) {
1042010426 firstValueDeclaration = prop.valueDeclaration;
1042110427 }
10422- else if (prop.valueDeclaration !== firstValueDeclaration) {
10428+ else if (prop.valueDeclaration && prop.valueDeclaration !== firstValueDeclaration) {
1042310429 hasNonUniformValueDeclaration = true;
1042410430 }
1042510431 declarations = addRange(declarations, prop.declarations);
@@ -14545,6 +14551,16 @@ namespace ts {
1454514551 }
1454614552 }
1454714553
14554+ function checkExpressionForMutableLocationWithContextualType(next: Expression, sourcePropType: Type) {
14555+ next.contextualType = sourcePropType;
14556+ try {
14557+ return checkExpressionForMutableLocation(next, CheckMode.Contextual, sourcePropType);
14558+ }
14559+ finally {
14560+ next.contextualType = undefined;
14561+ }
14562+ }
14563+
1454814564 type ElaborationIterator = IterableIterator<{ errorNode: Node, innerExpression: Expression | undefined, nameType: Type, errorMessage?: DiagnosticMessage | undefined }>;
1454914565 /**
1455014566 * For every element returned from the iterator, checks that element to issue an error on a property of that element's type
@@ -14575,7 +14591,7 @@ namespace ts {
1457514591 // Issue error on the prop itself, since the prop couldn't elaborate the error
1457614592 const resultObj: { errors?: Diagnostic[] } = errorOutputContainer || {};
1457714593 // Use the expression type, if available
14578- const specificSource = next ? checkExpressionForMutableLocation (next, CheckMode.Normal , sourcePropType) : sourcePropType;
14594+ const specificSource = next ? checkExpressionForMutableLocationWithContextualType (next, sourcePropType) : sourcePropType;
1457914595 const result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage, containingMessageChain, resultObj);
1458014596 if (result && specificSource !== sourcePropType) {
1458114597 // If for whatever reason the expression type doesn't yield an error, make sure we still issue an error on the sourcePropType
@@ -15230,6 +15246,7 @@ namespace ts {
1523015246 let overrideNextErrorInfo = 0; // How many `reportRelationError` calls should be skipped in the elaboration pyramid
1523115247 let lastSkippedInfo: [Type, Type] | undefined;
1523215248 let incompatibleStack: [DiagnosticMessage, (string | number)?, (string | number)?, (string | number)?, (string | number)?][] = [];
15249+ let inPropertyCheck = false;
1523315250
1523415251 Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking");
1523515252
@@ -15238,7 +15255,7 @@ namespace ts {
1523815255 reportIncompatibleStack();
1523915256 }
1524015257 if (overflow) {
15241- const diag = error(errorNode, Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target));
15258+ const diag = error(errorNode || currentNode , Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target));
1524215259 if (errorOutputContainer) {
1524315260 (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag);
1524415261 }
@@ -15665,10 +15682,15 @@ namespace ts {
1566515682 // function foo<T extends object>(x: { a?: string }, y: T & { a: boolean }) {
1566615683 // x = y; // Mismatched property in source intersection
1566715684 // }
15668- if (result && (
15685+ //
15686+ // We suppress recursive intersection property checks because they can generate lots of work when relating
15687+ // recursive intersections that are structurally similar but not exactly identical. See #37854.
15688+ if (result && !inPropertyCheck && (
1566915689 target.flags & TypeFlags.Intersection && (isPerformingExcessPropertyChecks || isPerformingCommonPropertyChecks) ||
1567015690 isNonGenericObjectType(target) && source.flags & TypeFlags.Intersection && getApparentType(source).flags & TypeFlags.StructuredType && !some((<IntersectionType>source).types, t => !!(getObjectFlags(t) & ObjectFlags.NonInferrableType)))) {
15691+ inPropertyCheck = true;
1567115692 result &= recursiveTypeRelatedTo(source, target, reportErrors, IntersectionState.PropertyCheck);
15693+ inPropertyCheck = false;
1567215694 }
1567315695
1567415696 if (!result && reportErrors) {
@@ -15965,7 +15987,7 @@ namespace ts {
1596515987 if (overflow) {
1596615988 return Ternary.False;
1596715989 }
15968- const id = getRelationKey(source, target, intersectionState, relation);
15990+ const id = getRelationKey(source, target, intersectionState | (inPropertyCheck ? IntersectionState.InPropertyCheck : 0) , relation);
1596915991 const entry = relation.get(id);
1597015992 if (entry !== undefined) {
1597115993 if (reportErrors && entry & RelationComparisonResult.Failed && !(entry & RelationComparisonResult.Reported)) {
@@ -27243,7 +27265,7 @@ namespace ts {
2724327265 }
2724427266
2724527267 const functionFlags = getFunctionFlags(func);
27246- const type = returnType && getReturnOrPromisedType (returnType, functionFlags);
27268+ const type = returnType && unwrapReturnType (returnType, functionFlags);
2724727269
2724827270 // Functions with with an explicitly specified 'void' or 'any' return type don't need any return expressions.
2724927271 if (type && maybeTypeOfKind(type, TypeFlags.Any | TypeFlags.Void)) {
@@ -27363,14 +27385,6 @@ namespace ts {
2736327385 }
2736427386 }
2736527387
27366- function getReturnOrPromisedType(type: Type | undefined, functionFlags: FunctionFlags) {
27367- const isGenerator = !!(functionFlags & FunctionFlags.Generator);
27368- const isAsync = !!(functionFlags & FunctionFlags.Async);
27369- return type && isGenerator ? getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, type, isAsync) || errorType :
27370- type && isAsync ? getAwaitedType(type) || errorType :
27371- type;
27372- }
27373-
2737427388 function checkFunctionExpressionOrObjectLiteralMethodDeferred(node: ArrowFunction | FunctionExpression | MethodDeclaration) {
2737527389 Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
2737627390
@@ -27398,7 +27412,7 @@ namespace ts {
2739827412 // check assignability of the awaited type of the expression body against the promised type of
2739927413 // its return type annotation.
2740027414 const exprType = checkExpression(node.body);
27401- const returnOrPromisedType = getReturnOrPromisedType (returnType, functionFlags);
27415+ const returnOrPromisedType = returnType && unwrapReturnType (returnType, functionFlags);
2740227416 if (returnOrPromisedType) {
2740327417 if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async) { // Async function
2740427418 const awaitedType = checkAwaitedType(exprType, node.body, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
@@ -32686,8 +32700,8 @@ namespace ts {
3268632700 function unwrapReturnType(returnType: Type, functionFlags: FunctionFlags) {
3268732701 const isGenerator = !!(functionFlags & FunctionFlags.Generator);
3268832702 const isAsync = !!(functionFlags & FunctionFlags.Async);
32689- return isGenerator ? getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, isAsync) || errorType :
32690- isAsync ? getPromisedTypeOfPromise (returnType) || errorType :
32703+ return isGenerator ? getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, isAsync) ?? errorType :
32704+ isAsync ? getAwaitedType (returnType) ?? errorType :
3269132705 returnType;
3269232706 }
3269332707
@@ -32724,7 +32738,7 @@ namespace ts {
3272432738 }
3272532739 }
3272632740 else if (getReturnTypeFromAnnotation(func)) {
32727- const unwrappedReturnType = unwrapReturnType(returnType, functionFlags);
32741+ const unwrappedReturnType = unwrapReturnType(returnType, functionFlags) ?? returnType ;
3272832742 const unwrappedExprType = functionFlags & FunctionFlags.Async
3272932743 ? checkAwaitedType(exprType, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
3273032744 : exprType;
@@ -32936,6 +32950,10 @@ namespace ts {
3293632950 const propDeclaration = prop.valueDeclaration;
3293732951 const name = propDeclaration && getNameOfDeclaration(propDeclaration);
3293832952
32953+ if (name && isPrivateIdentifier(name)) {
32954+ return;
32955+ }
32956+
3293932957 // index is numeric and property name is not valid numeric literal
3294032958 if (indexKind === IndexKind.Number && !(name ? isNumericName(name) : isNumericLiteralName(prop.escapedName))) {
3294132959 return;
@@ -34015,7 +34033,7 @@ namespace ts {
3401534033 return false;
3401634034 }
3401734035 if (inAmbientExternalModule && isExternalModuleNameRelative(moduleName.text)) {
34018- // we have already reported errors on top level imports\ exports in external module augmentations in checkModuleDeclaration
34036+ // we have already reported errors on top level imports/ exports in external module augmentations in checkModuleDeclaration
3401934037 // no need to do this again.
3402034038 if (!isTopLevelInExternalModuleAugmentation(node)) {
3402134039 // TypeScript 1.0 spec (April 2013): 12.1.6
@@ -34151,16 +34169,10 @@ namespace ts {
3415134169
3415234170 checkGrammarExportDeclaration(node);
3415334171 if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) {
34154- if (node.exportClause) {
34172+ if (node.exportClause && !isNamespaceExport(node.exportClause) ) {
3415534173 // export { x, y }
3415634174 // export { x, y } from "foo"
34157- if (isNamedExports(node.exportClause)) {
34158- forEach(node.exportClause.elements, checkExportSpecifier);
34159- }
34160- else if(!isNamespaceExport(node.exportClause)) {
34161- checkImportBinding(node.exportClause);
34162- }
34163-
34175+ forEach(node.exportClause.elements, checkExportSpecifier);
3416434176 const inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && isAmbientModule(node.parent.parent);
3416534177 const inAmbientNamespaceDeclaration = !inAmbientExternalModule && node.parent.kind === SyntaxKind.ModuleBlock &&
3416634178 !node.moduleSpecifier && node.flags & NodeFlags.Ambient;
@@ -34174,7 +34186,9 @@ namespace ts {
3417434186 if (moduleSymbol && hasExportAssignmentSymbol(moduleSymbol)) {
3417534187 error(node.moduleSpecifier, Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol));
3417634188 }
34177-
34189+ else if (node.exportClause) {
34190+ checkAliasSymbol(node.exportClause);
34191+ }
3417834192 if (moduleKind !== ModuleKind.System && moduleKind < ModuleKind.ES2015) {
3417934193 checkExternalEmitHelpers(node, ExternalEmitHelpers.ExportStar);
3418034194 }
0 commit comments