@@ -6769,9 +6769,20 @@ module ts {
67696769 let argCount = getEffectiveArgumentCount(node, args, signature);
67706770 for (let i = 0; i < argCount; i++) {
67716771 let arg = getEffectiveArgument(node, args, i);
6772- if (!arg || arg.kind !== SyntaxKind.OmittedExpression) {
6772+ // If the effective argument is 'undefined', then it is an argument that is present but is synthetic.
6773+ if (arg === undefined || arg.kind !== SyntaxKind.OmittedExpression) {
67736774 let paramType = getTypeAtPosition(signature, i);
6774- let argType = getEffectiveArgumentType(node, i, arg, paramType, excludeArgument, inferenceMapper, /*reportErrors*/ false);
6775+ let argType = getEffectiveArgumentType(node, i, arg);
6776+
6777+ // If the effective argument type is 'undefined', there is no synthetic type
6778+ // for the argument. In that case, we should check the argument.
6779+ if (argType === undefined) {
6780+ // For context sensitive arguments we pass the identityMapper, which is a signal to treat all
6781+ // context sensitive function expressions as wildcards
6782+ let mapper = excludeArgument && excludeArgument[i] !== undefined ? identityMapper : inferenceMapper;
6783+ argType = checkExpressionWithContextualType(arg, paramType, mapper);
6784+ }
6785+
67756786 inferTypes(context, argType, paramType);
67766787 }
67776788 }
@@ -6830,10 +6841,19 @@ module ts {
68306841 let argCount = getEffectiveArgumentCount(node, args, signature);
68316842 for (let i = 0; i < argCount; i++) {
68326843 let arg = getEffectiveArgument(node, args, i);
6833- if (!arg || arg.kind !== SyntaxKind.OmittedExpression) {
6844+ // If the effective argument is 'undefined', then it is an argument that is present but is synthetic.
6845+ if (arg === undefined || arg.kind !== SyntaxKind.OmittedExpression) {
68346846 // Check spread elements against rest type (from arity check we know spread argument corresponds to a rest parameter)
68356847 let paramType = getTypeAtPosition(signature, i);
6836- let argType = getEffectiveArgumentType(node, i, arg, paramType, excludeArgument, /*inferenceMapper*/ undefined, reportErrors);
6848+ let argType = getEffectiveArgumentType(node, i, arg);
6849+
6850+ // If the effective argument type is 'undefined', there is no synthetic type
6851+ // for the argument. In that case, we should check the argument.
6852+ if (argType === undefined) {
6853+ argType = arg.kind === SyntaxKind.StringLiteral && !reportErrors
6854+ ? getStringLiteralType(<StringLiteral>arg)
6855+ : checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
6856+ }
68376857
68386858 // Use argument expression as error location when reporting errors
68396859 let errorNode = reportErrors ? getEffectiveArgumentErrorNode(node, i, arg) : undefined;
@@ -7126,7 +7146,7 @@ module ts {
71267146 /**
71277147 * Gets the effective argument type for an argument in a call expression.
71287148 */
7129- function getEffectiveArgumentType(node: CallLikeExpression, argIndex: number, arg: Expression, paramType: Type, excludeArgument: boolean[], inferenceMapper: TypeMapper, reportErrors: boolean ): Type {
7149+ function getEffectiveArgumentType(node: CallLikeExpression, argIndex: number, arg: Expression): Type {
71307150 // Decorators provide special arguments, a tagged template expression provides
71317151 // a special first argument, and string literals get string literal types
71327152 // unless we're reporting errors
@@ -7136,20 +7156,10 @@ module ts {
71367156 else if (argIndex === 0 && node.kind === SyntaxKind.TaggedTemplateExpression) {
71377157 return globalTemplateStringsArrayType;
71387158 }
7139- else if (!inferenceMapper && !reportErrors && arg.kind === SyntaxKind.StringLiteral) {
7140- return getStringLiteralType(<StringLiteral>arg);
7141- }
7142- else {
7143- let mapper: TypeMapper;
7144- if (inferenceMapper) {
7145- mapper = excludeArgument && excludeArgument[argIndex] !== undefined ? identityMapper : inferenceMapper;
7146- }
7147- else {
7148- mapper = excludeArgument && excludeArgument[argIndex] ? identityMapper : undefined;
7149- }
71507159
7151- return checkExpressionWithContextualType(arg, paramType, mapper);
7152- }
7160+ // This is not a synthetic argument, so we return 'undefined'
7161+ // to signal that the caller needs to check the argument.
7162+ return undefined;
71537163 }
71547164
71557165 /**
0 commit comments