Fixed error spans for SatisfiesExpression check nodes (#56918)

This commit is contained in:
Mateusz Burzyński
2024-01-19 23:11:12 +01:00
committed by GitHub
parent 1982349339
commit 10a63a9bb8
5 changed files with 572 additions and 6 deletions

View File

@@ -700,6 +700,7 @@ import {
isRightSideOfQualifiedNameOrPropertyAccess,
isRightSideOfQualifiedNameOrPropertyAccessOrJSDocMemberName,
isSameEntityName,
isSatisfiesExpression,
isSetAccessor,
isSetAccessorDeclaration,
isShorthandAmbientModuleSymbol,
@@ -20654,7 +20655,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const elem = node.elements[i];
if (isOmittedExpression(elem)) continue;
const nameType = getNumberLiteralType(i);
yield { errorNode: elem, innerExpression: elem, nameType };
const checkNode = getEffectiveCheckNode(elem);
yield { errorNode: checkNode, innerExpression: checkNode, nameType };
}
}
@@ -34190,6 +34192,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
function getEffectiveCheckNode(argument: Expression): Expression {
argument = skipParentheses(argument);
return isSatisfiesExpression(argument) ? skipParentheses(argument.expression) : argument;
}
function getSignatureApplicabilityError(
node: CallLikeExpression,
args: readonly Expression[],
@@ -34233,7 +34240,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// we obtain the regular type of any object literal arguments because we may not have inferred complete
// parameter types yet and therefore excess property checks may yield false positives (see #17041).
const checkArgType = checkMode & CheckMode.SkipContextSensitive ? getRegularTypeOfObjectLiteral(argType) : argType;
if (!checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? arg : undefined, arg, headMessage, containingMessageChain, errorOutputContainer)) {
const effectiveCheckArgumentNode = getEffectiveCheckNode(arg);
if (!checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? effectiveCheckArgumentNode : undefined, effectiveCheckArgumentNode, headMessage, containingMessageChain, errorOutputContainer)) {
Debug.assert(!reportErrors || !!errorOutputContainer.errors, "parameter should have errors when reporting errors");
maybeAddMissingAwaitInfo(arg, checkArgType, paramType);
return errorOutputContainer.errors || emptyArray;
@@ -34245,7 +34253,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const restArgCount = args.length - argCount;
const errorNode = !reportErrors ? undefined :
restArgCount === 0 ? node :
restArgCount === 1 ? args[argCount] :
restArgCount === 1 ? getEffectiveCheckNode(args[argCount]) :
setTextRangePosEnd(createSyntheticExpression(node, spreadType), args[argCount].pos, args[args.length - 1].end);
if (!checkTypeRelatedTo(spreadType, restType, relation, errorNode, headMessage, /*containingMessageChain*/ undefined, errorOutputContainer)) {
Debug.assert(!reportErrors || !!errorOutputContainer.errors, "rest parameter should have errors when reporting errors");
@@ -37536,12 +37544,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const exprType = checkExpression(node.body);
const returnOrPromisedType = returnType && unwrapReturnType(returnType, functionFlags);
if (returnOrPromisedType) {
const effectiveCheckNode = getEffectiveCheckNode(node.body);
if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async) { // Async function
const awaitedType = checkAwaitedType(exprType, /*withAlias*/ false, node.body, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
checkTypeAssignableToAndOptionallyElaborate(awaitedType, returnOrPromisedType, node.body, node.body);
const awaitedType = checkAwaitedType(exprType, /*withAlias*/ false, effectiveCheckNode, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
checkTypeAssignableToAndOptionallyElaborate(awaitedType, returnOrPromisedType, effectiveCheckNode, effectiveCheckNode);
}
else { // Normal function
checkTypeAssignableToAndOptionallyElaborate(exprType, returnOrPromisedType, node.body, node.body);
checkTypeAssignableToAndOptionallyElaborate(exprType, returnOrPromisedType, effectiveCheckNode, effectiveCheckNode);
}
}
}