@@ -29602,7 +29602,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2960229602 node.kind === SyntaxKind.PropertyDeclaration)!;
2960329603 }
2960429604
29605- // Check if a parameter or catch variable is assigned anywhere
29605+ // Check if a parameter, catch variable, or mutable local variable is assigned anywhere definitely
29606+ function isSymbolAssignedDefinitely(symbol: Symbol) {
29607+ if (symbol.lastAssignmentPos !== undefined) {
29608+ return symbol.lastAssignmentPos < 0;
29609+ }
29610+ return isSymbolAssigned(symbol) && symbol.lastAssignmentPos !== undefined && symbol.lastAssignmentPos < 0;
29611+ }
29612+
29613+ // Check if a parameter, catch variable, or mutable local variable is assigned anywhere
2960629614 function isSymbolAssigned(symbol: Symbol) {
2960729615 return !isPastLastAssignment(symbol, /*location*/ undefined);
2960829616 }
@@ -29621,7 +29629,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2962129629 markNodeAssignments(parent);
2962229630 }
2962329631 }
29624- return !symbol.lastAssignmentPos || location && symbol.lastAssignmentPos < location.pos;
29632+ return !symbol.lastAssignmentPos || location && Math.abs( symbol.lastAssignmentPos) < location.pos;
2962529633 }
2962629634
2962729635 // Check if a parameter or catch variable (or their bindings elements) is assigned anywhere
@@ -29655,12 +29663,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2965529663 function markNodeAssignments(node: Node) {
2965629664 switch (node.kind) {
2965729665 case SyntaxKind.Identifier:
29658- if (isAssignmentTarget(node)) {
29666+ const assigmentTarget = getAssignmentTargetKind(node);
29667+ if (assigmentTarget !== AssignmentKind.None) {
2965929668 const symbol = getResolvedSymbol(node as Identifier);
29660- if (isParameterOrMutableLocalVariable(symbol) && symbol.lastAssignmentPos !== Number.MAX_VALUE) {
29661- const referencingFunction = findAncestor(node, isFunctionOrSourceFile);
29662- const declaringFunction = findAncestor(symbol.valueDeclaration, isFunctionOrSourceFile);
29663- symbol.lastAssignmentPos = referencingFunction === declaringFunction ? extendAssignmentPosition(node, symbol.valueDeclaration!) : Number.MAX_VALUE;
29669+ const hasDefiniteAssignment = assigmentTarget === AssignmentKind.Definite || (symbol.lastAssignmentPos !== undefined && symbol.lastAssignmentPos < 0);
29670+ if (isParameterOrMutableLocalVariable(symbol)) {
29671+ if (symbol.lastAssignmentPos === undefined || Math.abs(symbol.lastAssignmentPos) !== Number.MAX_VALUE) {
29672+ const referencingFunction = findAncestor(node, isFunctionOrSourceFile);
29673+ const declaringFunction = findAncestor(symbol.valueDeclaration, isFunctionOrSourceFile);
29674+ symbol.lastAssignmentPos = referencingFunction === declaringFunction ? extendAssignmentPosition(node, symbol.valueDeclaration!) : Number.MAX_VALUE;
29675+ }
29676+ if (hasDefiniteAssignment && symbol.lastAssignmentPos > 0) {
29677+ symbol.lastAssignmentPos *= -1;
29678+ }
2966429679 }
2966529680 }
2966629681 return;
@@ -29670,7 +29685,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2967029685 if (!(node as ExportSpecifier).isTypeOnly && !exportDeclaration.isTypeOnly && !exportDeclaration.moduleSpecifier && name.kind !== SyntaxKind.StringLiteral) {
2967129686 const symbol = resolveEntityName(name, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ true);
2967229687 if (symbol && isParameterOrMutableLocalVariable(symbol)) {
29673- symbol.lastAssignmentPos = Number.MAX_VALUE;
29688+ const sign = symbol.lastAssignmentPos !== undefined && symbol.lastAssignmentPos < 0 ? -1 : 1;
29689+ symbol.lastAssignmentPos = sign * Number.MAX_VALUE;
2967429690 }
2967529691 }
2967629692 return;
@@ -30414,6 +30430,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3041430430
3041530431 const localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol);
3041630432 let declaration = localOrExportSymbol.valueDeclaration;
30433+ const immediateDeclaration = declaration;
3041730434
3041830435 // If the identifier is declared in a binding pattern for which we're currently computing the implied type and the
3041930436 // reference occurs with the same binding pattern, return the non-inferrable any type. This for example occurs in
@@ -30503,7 +30520,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3050330520 // We only look for uninitialized variables in strict null checking mode, and only when we can analyze
3050430521 // the entire control flow graph from the variable's declaration (i.e. when the flow container and
3050530522 // declaration container are the same).
30506- const assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || isSameScopedBindingElement(node, declaration) ||
30523+ const isNeverInitialized = immediateDeclaration && isVariableDeclaration(immediateDeclaration) && !immediateDeclaration.initializer && !immediateDeclaration.exclamationToken && isMutableLocalVariableDeclaration(immediateDeclaration) && !isSymbolAssignedDefinitely(symbol);
30524+ const assumeInitialized = isParameter || isAlias ||
30525+ (isOuterVariable && !isNeverInitialized) ||
30526+ isSpreadDestructuringAssignmentTarget || isModuleExports || isSameScopedBindingElement(node, declaration) ||
3050730527 type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Void)) !== 0 ||
3050830528 isInTypeQuery(node) || isInAmbientOrTypeNode(node) || node.parent.kind === SyntaxKind.ExportSpecifier) ||
3050930529 node.parent.kind === SyntaxKind.NonNullExpression ||
@@ -43495,7 +43515,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4349543515 case SyntaxKind.MethodDeclaration:
4349643516 case SyntaxKind.GetAccessor:
4349743517 case SyntaxKind.SetAccessor:
43498- if (node.body) { // Don't report unused parameters in overloads
43518+ // Only report unused parameters on the implementation, not overloads.
43519+ if (node.body) {
4349943520 checkUnusedLocalsAndParameters(node, addDiagnostic);
4350043521 }
4350143522 checkUnusedTypeParameters(node, addDiagnostic);
0 commit comments