@@ -17842,6 +17842,13 @@ namespace ts {
17842
17842
message = Diagnostics.Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_types_of_the_target_s_properties;
17843
17843
}
17844
17844
else {
17845
+ if (source.flags & TypeFlags.StringLiteral && target.flags & TypeFlags.Union) {
17846
+ const suggestedType = getSuggestedTypeForNonexistentStringLiteralType(source as StringLiteralType, target as UnionType);
17847
+ if (suggestedType) {
17848
+ reportError(Diagnostics.Type_0_is_not_assignable_to_type_1_Did_you_mean_2, generalizedSourceType, targetType, typeToString(suggestedType));
17849
+ return;
17850
+ }
17851
+ }
17845
17852
message = Diagnostics.Type_0_is_not_assignable_to_type_1;
17846
17853
}
17847
17854
}
@@ -23244,9 +23251,10 @@ namespace ts {
23244
23251
23245
23252
function isConstantReference(node: Node): boolean {
23246
23253
switch (node.kind) {
23247
- case SyntaxKind.Identifier:
23254
+ case SyntaxKind.Identifier: {
23248
23255
const symbol = getResolvedSymbol(node as Identifier);
23249
- return isConstVariable(symbol) || !!symbol.valueDeclaration && getRootDeclaration(symbol.valueDeclaration).kind === SyntaxKind.Parameter && !isParameterAssigned(symbol);
23256
+ return isConstVariable(symbol) || isParameterOrCatchClauseVariable(symbol) && !isSymbolAssigned(symbol);
23257
+ }
23250
23258
case SyntaxKind.PropertyAccessExpression:
23251
23259
case SyntaxKind.ElementAccessExpression:
23252
23260
// The resolvedSymbol property is initialized by checkPropertyAccess or checkElementAccess before we get here.
@@ -24380,37 +24388,38 @@ namespace ts {
24380
24388
node.kind === SyntaxKind.PropertyDeclaration)!;
24381
24389
}
24382
24390
24383
- // Check if a parameter is assigned anywhere within its declaring function.
24384
- function isParameterAssigned (symbol: Symbol) {
24391
+ // Check if a parameter or catch variable is assigned anywhere
24392
+ function isSymbolAssigned (symbol: Symbol) {
24385
24393
if (!symbol.valueDeclaration) {
24386
24394
return false;
24387
24395
}
24388
- const func = getRootDeclaration(symbol.valueDeclaration).parent as FunctionLikeDeclaration ;
24389
- const links = getNodeLinks(func );
24396
+ const parent = getRootDeclaration(symbol.valueDeclaration).parent;
24397
+ const links = getNodeLinks(parent );
24390
24398
if (!(links.flags & NodeCheckFlags.AssignmentsMarked)) {
24391
24399
links.flags |= NodeCheckFlags.AssignmentsMarked;
24392
- if (!hasParentWithAssignmentsMarked(func )) {
24393
- markParameterAssignments(func );
24400
+ if (!hasParentWithAssignmentsMarked(parent )) {
24401
+ markNodeAssignments(parent );
24394
24402
}
24395
24403
}
24396
24404
return symbol.isAssigned || false;
24397
24405
}
24398
24406
24399
24407
function hasParentWithAssignmentsMarked(node: Node) {
24400
- return !!findAncestor(node.parent, node => isFunctionLike(node) && !!(getNodeLinks(node).flags & NodeCheckFlags.AssignmentsMarked));
24408
+ return !!findAncestor(node.parent, node =>
24409
+ (isFunctionLike(node) || isCatchClause(node)) && !!(getNodeLinks(node).flags & NodeCheckFlags.AssignmentsMarked));
24401
24410
}
24402
24411
24403
- function markParameterAssignments (node: Node) {
24412
+ function markNodeAssignments (node: Node) {
24404
24413
if (node.kind === SyntaxKind.Identifier) {
24405
24414
if (isAssignmentTarget(node)) {
24406
24415
const symbol = getResolvedSymbol(node as Identifier);
24407
- if (symbol.valueDeclaration && getRootDeclaration (symbol.valueDeclaration).kind === SyntaxKind.Parameter ) {
24416
+ if (isParameterOrCatchClauseVariable (symbol) ) {
24408
24417
symbol.isAssigned = true;
24409
24418
}
24410
24419
}
24411
24420
}
24412
24421
else {
24413
- forEachChild(node, markParameterAssignments );
24422
+ forEachChild(node, markNodeAssignments );
24414
24423
}
24415
24424
}
24416
24425
@@ -24479,7 +24488,19 @@ namespace ts {
24479
24488
}
24480
24489
24481
24490
function isExportOrExportExpression(location: Node) {
24482
- return !!findAncestor(location, e => e.parent && isExportAssignment(e.parent) && e.parent.expression === e && isEntityNameExpression(e));
24491
+ return !!findAncestor(location, n => {
24492
+ const parent = n.parent;
24493
+ if (parent === undefined) {
24494
+ return "quit";
24495
+ }
24496
+ if (isExportAssignment(parent)) {
24497
+ return parent.expression === n && isEntityNameExpression(n);
24498
+ }
24499
+ if (isExportSpecifier(parent)) {
24500
+ return parent.name === n || parent.propertyName === n;
24501
+ }
24502
+ return false;
24503
+ });
24483
24504
}
24484
24505
24485
24506
function markAliasReferenced(symbol: Symbol, location: Node) {
@@ -24648,7 +24669,7 @@ namespace ts {
24648
24669
// analysis to include the immediately enclosing function.
24649
24670
while (flowContainer !== declarationContainer && (flowContainer.kind === SyntaxKind.FunctionExpression ||
24650
24671
flowContainer.kind === SyntaxKind.ArrowFunction || isObjectLiteralOrClassExpressionMethodOrAccessor(flowContainer)) &&
24651
- (isConstVariable(localOrExportSymbol) && type !== autoArrayType || isParameter && !isParameterAssigned (localOrExportSymbol))) {
24672
+ (isConstVariable(localOrExportSymbol) && type !== autoArrayType || isParameter && !isSymbolAssigned (localOrExportSymbol))) {
24652
24673
flowContainer = getControlFlowContainer(flowContainer);
24653
24674
}
24654
24675
// We only look for uninitialized variables in strict null checking mode, and only when we can analyze
@@ -28241,6 +28262,11 @@ namespace ts {
28241
28262
return suggestion;
28242
28263
}
28243
28264
28265
+ function getSuggestedTypeForNonexistentStringLiteralType(source: StringLiteralType, target: UnionType): StringLiteralType | undefined {
28266
+ const candidates = target.types.filter((type): type is StringLiteralType => !!(type.flags & TypeFlags.StringLiteral));
28267
+ return getSpellingSuggestion(source.value, candidates, type => type.value);
28268
+ }
28269
+
28244
28270
/**
28245
28271
* Given a name and a list of symbols whose names are *not* equal to the name, return a spelling suggestion if there is one that is close enough.
28246
28272
* Names less than length 3 only check for case-insensitive equality, not levenshtein distance.
@@ -38047,6 +38073,7 @@ namespace ts {
38047
38073
function checkClassMember(member: ClassElement | ParameterPropertyDeclaration, memberIsParameterProperty?: boolean) {
38048
38074
const hasOverride = hasOverrideModifier(member);
38049
38075
const hasStatic = isStatic(member);
38076
+ const isJs = isInJSFile(member);
38050
38077
if (baseWithThis && (hasOverride || compilerOptions.noImplicitOverride)) {
38051
38078
const declaredProp = member.name && getSymbolAtLocation(member.name) || getSymbolAtLocation(member);
38052
38079
if (!declaredProp) {
@@ -38062,8 +38089,19 @@ namespace ts {
38062
38089
if (prop && !baseProp && hasOverride) {
38063
38090
const suggestion = getSuggestedSymbolForNonexistentClassMember(symbolName(declaredProp), baseType);
38064
38091
suggestion ?
38065
- error(member, Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1, baseClassName, symbolToString(suggestion)) :
38066
- error(member, Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0, baseClassName);
38092
+ error(
38093
+ member,
38094
+ isJs ?
38095
+ Diagnostics.This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1 :
38096
+ Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1,
38097
+ baseClassName,
38098
+ symbolToString(suggestion)) :
38099
+ error(
38100
+ member,
38101
+ isJs ?
38102
+ Diagnostics.This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_it_is_not_declared_in_the_base_class_0 :
38103
+ Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0,
38104
+ baseClassName);
38067
38105
}
38068
38106
else if (prop && baseProp?.declarations && compilerOptions.noImplicitOverride && !nodeInAmbientContext) {
38069
38107
const baseHasAbstract = some(baseProp.declarations, hasAbstractModifier);
@@ -38073,8 +38111,12 @@ namespace ts {
38073
38111
38074
38112
if (!baseHasAbstract) {
38075
38113
const diag = memberIsParameterProperty ?
38076
- Diagnostics.This_parameter_property_must_have_an_override_modifier_because_it_overrides_a_member_in_base_class_0 :
38077
- Diagnostics.This_member_must_have_an_override_modifier_because_it_overrides_a_member_in_the_base_class_0;
38114
+ isJs ?
38115
+ Diagnostics.This_parameter_property_must_have_a_JSDoc_comment_with_an_override_tag_because_it_overrides_a_member_in_the_base_class_0 :
38116
+ Diagnostics.This_parameter_property_must_have_an_override_modifier_because_it_overrides_a_member_in_base_class_0 :
38117
+ isJs ?
38118
+ Diagnostics.This_member_must_have_a_JSDoc_comment_with_an_override_tag_because_it_overrides_a_member_in_the_base_class_0 :
38119
+ Diagnostics.This_member_must_have_an_override_modifier_because_it_overrides_a_member_in_the_base_class_0;
38078
38120
error(member, diag, baseClassName);
38079
38121
}
38080
38122
else if (hasAbstractModifier(member) && baseHasAbstract) {
@@ -38084,7 +38126,12 @@ namespace ts {
38084
38126
}
38085
38127
else if (hasOverride) {
38086
38128
const className = typeToString(type);
38087
- error(member, Diagnostics.This_member_cannot_have_an_override_modifier_because_its_containing_class_0_does_not_extend_another_class, className);
38129
+ error(
38130
+ member,
38131
+ isJs ?
38132
+ Diagnostics.This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_its_containing_class_0_does_not_extend_another_class :
38133
+ Diagnostics.This_member_cannot_have_an_override_modifier_because_its_containing_class_0_does_not_extend_another_class,
38134
+ className);
38088
38135
}
38089
38136
}
38090
38137
}
0 commit comments