Improved errors for required parameters with default values in isolated declaration (#58637)

This commit is contained in:
Titian Cernicova-Dragomir
2024-05-24 11:50:47 -07:00
committed by GitHub
parent 6856735985
commit 842cf177db
10 changed files with 446 additions and 21 deletions
+6 -6
View File
@@ -6116,7 +6116,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return result;
}
}
context.tracker.reportInferenceFallback(existing);
return undefined;
}
@@ -8217,6 +8216,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function serializeTypeForDeclaration(context: NodeBuilderContext, declaration: Declaration | undefined, type: Type, symbol: Symbol) {
const addUndefined = declaration && (isParameter(declaration) || isJSDocParameterTag(declaration)) && requiresAddingImplicitUndefined(declaration);
const enclosingDeclaration = context.enclosingDeclaration;
const oldFlags = context.flags;
if (declaration && hasInferredType(declaration) && !(context.flags & NodeBuilderFlags.NoSyntacticPrinter)) {
syntacticNodeBuilder.serializeTypeOfDeclaration(declaration, context);
}
context.flags |= NodeBuilderFlags.NoSyntacticPrinter;
if (enclosingDeclaration && (!isErrorType(type) || (context.flags & NodeBuilderFlags.AllowUnresolvedNames))) {
const declWithExistingAnnotation = declaration && getNonlocalEffectiveTypeAnnotationNode(declaration)
? declaration
@@ -8226,11 +8230,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const existing = getNonlocalEffectiveTypeAnnotationNode(declWithExistingAnnotation)!;
const result = !isTypePredicateNode(existing) && tryReuseExistingTypeNode(context, existing, type, declWithExistingAnnotation, addUndefined);
if (result) {
context.flags = oldFlags;
return result;
}
}
}
const oldFlags = context.flags;
if (
type.flags & TypeFlags.UniqueESSymbol &&
type.symbol === symbol && (!context.enclosingDeclaration || some(symbol.declarations, d => getSourceFileOfNode(d) === getSourceFileOfNode(context.enclosingDeclaration!)))
@@ -8241,10 +8245,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const decl = declaration ?? symbol.valueDeclaration ?? symbol.declarations?.[0];
const expr = decl && isDeclarationWithPossibleInnerTypeNodeReuse(decl) ? getPossibleTypeNodeReuseExpression(decl) : undefined;
if (decl && hasInferredType(decl) && !(context.flags & NodeBuilderFlags.NoSyntacticPrinter)) {
syntacticNodeBuilder.serializeTypeOfDeclaration(decl, context);
}
context.flags |= NodeBuilderFlags.NoSyntacticPrinter;
const result = expressionOrTypeToTypeNode(context, expr, type, addUndefined);
context.flags = oldFlags;
return result;
+7 -8
View File
@@ -32,7 +32,6 @@ import {
isIdentifier,
isJSDocTypeAssertion,
isKeyword,
isParameter,
isPrimitiveLiteralValue,
isShorthandPropertyAssignment,
isSpreadAssignment,
@@ -76,8 +75,8 @@ export function createSyntacticTypeNodeBuilder(options: CompilerOptions, resolve
serializeReturnTypeForSignature,
serializeTypeOfExpression,
};
function serializeExistingTypeAnnotation(type: TypeNode | undefined) {
return type === undefined ? undefined : !type.parent || !isParameter(type.parent) || !resolver.requiresAddingImplicitUndefined(type.parent) || canAddUndefined(type);
function serializeExistingTypeAnnotation(type: TypeNode | undefined, addUndefined?: boolean) {
return type !== undefined && (!addUndefined || (type && canAddUndefined(type))) ? true : undefined;
}
function serializeTypeOfExpression(expr: Expression, context: SyntacticTypeNodeBuilderContext, addUndefined?: boolean, preserveLiterals?: boolean) {
return typeFromExpression(expr, context, /*isConstContext*/ false, addUndefined, preserveLiterals) ?? inferExpressionType(expr, context);
@@ -181,12 +180,12 @@ export function createSyntacticTypeNodeBuilder(options: CompilerOptions, resolve
const declaredType = getEffectiveTypeAnnotationNode(node);
const addUndefined = resolver.requiresAddingImplicitUndefined(node);
let resultType;
if (!addUndefined) {
if (declaredType) {
return serializeExistingTypeAnnotation(declaredType);
}
if (declaredType) {
resultType = serializeExistingTypeAnnotation(declaredType, addUndefined);
}
else {
if (node.initializer && isIdentifier(node.name)) {
resultType = typeFromExpression(node.initializer, context);
resultType = typeFromExpression(node.initializer, context, /*isConstContext*/ undefined, addUndefined);
}
}
return resultType ?? inferTypeOfDeclaration(node, context);