@@ -15238,17 +15238,17 @@ namespace ts {
15238
15238
if (arg === undefined || arg.kind !== SyntaxKind.OmittedExpression) {
15239
15239
// Check spread elements against rest type (from arity check we know spread argument corresponds to a rest parameter)
15240
15240
const paramType = getTypeAtPosition(signature, i);
15241
- let argType = getEffectiveArgumentType(node, i);
15242
-
15243
- // If the effective argument type is 'undefined', there is no synthetic type
15244
- // for the argument. In that case, we should check the argument.
15245
- if (argType === undefined) {
15246
- argType = checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
15247
- }
15248
-
15241
+ // If the effective argument type is undefined, there is no synthetic type for the argument.
15242
+ // In that case, we should check the argument.
15243
+ const argType = getEffectiveArgumentType(node, i) ||
15244
+ checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
15245
+ // If one or more arguments are still excluded (as indicated by a non-null excludeArgument parameter),
15246
+ // we obtain the regular type of any object literal arguments because we may not have inferred complete
15247
+ // parameter types yet and therefore excess property checks may yield false positives (see #17041).
15248
+ const checkArgType = excludeArgument ? getRegularTypeOfObjectLiteral(argType) : argType;
15249
15249
// Use argument expression as error location when reporting errors
15250
15250
const errorNode = reportErrors ? getEffectiveArgumentErrorNode(node, i, arg) : undefined;
15251
- if (!checkTypeRelatedTo(argType , paramType, relation, errorNode, headMessage)) {
15251
+ if (!checkTypeRelatedTo(checkArgType , paramType, relation, errorNode, headMessage)) {
15252
15252
return false;
15253
15253
}
15254
15254
}
@@ -15620,6 +15620,7 @@ namespace ts {
15620
15620
// For a decorator, no arguments are susceptible to contextual typing due to the fact
15621
15621
// decorators are applied to a declaration by the emitter, and not to an expression.
15622
15622
let excludeArgument: boolean[];
15623
+ let excludeCount = 0;
15623
15624
if (!isDecorator) {
15624
15625
// We do not need to call `getEffectiveArgumentCount` here as it only
15625
15626
// applies when calculating the number of arguments for a decorator.
@@ -15629,6 +15630,7 @@ namespace ts {
15629
15630
excludeArgument = new Array(args.length);
15630
15631
}
15631
15632
excludeArgument[i] = true;
15633
+ excludeCount++;
15632
15634
}
15633
15635
}
15634
15636
}
@@ -15803,12 +15805,17 @@ namespace ts {
15803
15805
candidateForArgumentError = candidate;
15804
15806
break;
15805
15807
}
15806
- const index = excludeArgument ? indexOf(excludeArgument, /*value*/ true) : -1;
15807
- if (index < 0) {
15808
+ if (excludeCount === 0) {
15808
15809
candidates[candidateIndex] = candidate;
15809
15810
return candidate;
15810
15811
}
15811
- excludeArgument[index] = false;
15812
+ excludeCount--;
15813
+ if (excludeCount > 0) {
15814
+ excludeArgument[indexOf(excludeArgument, /*value*/ true)] = false;
15815
+ }
15816
+ else {
15817
+ excludeArgument = undefined;
15818
+ }
15812
15819
}
15813
15820
}
15814
15821
0 commit comments