@@ -31113,7 +31113,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3111331113 // We only look for uninitialized variables in strict null checking mode, and only when we can analyze
3111431114 // the entire control flow graph from the variable's declaration (i.e. when the flow container and
3111531115 // declaration container are the same).
31116- const isNeverInitialized = immediateDeclaration && isVariableDeclaration(immediateDeclaration) && !immediateDeclaration.initializer && !immediateDeclaration.exclamationToken && isMutableLocalVariableDeclaration(immediateDeclaration) && !isSymbolAssignedDefinitely(symbol);
31116+ const isNeverInitialized = immediateDeclaration && isVariableDeclaration(immediateDeclaration) && !isForInOrOfStatement(immediateDeclaration.parent.parent) && ! immediateDeclaration.initializer && !immediateDeclaration.exclamationToken && isMutableLocalVariableDeclaration(immediateDeclaration) && !isSymbolAssignedDefinitely(symbol);
3111731117 const assumeInitialized = isParameter || isAlias ||
3111831118 (isOuterVariable && !isNeverInitialized) ||
3111931119 isSpreadDestructuringAssignmentTarget || isModuleExports || isSameScopedBindingElement(node, declaration) ||
@@ -40548,12 +40548,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4054840548 }
4054940549 }
4055040550 checkNullishCoalesceOperandLeft(node);
40551- checkNullishCoalesceOperandRight(node);
4055240551 }
4055340552
4055440553 function checkNullishCoalesceOperandLeft(node: BinaryExpression) {
4055540554 const leftTarget = skipOuterExpressions(node.left, OuterExpressionKinds.All);
40556-
4055740555 const nullishSemantics = getSyntacticNullishnessSemantics(leftTarget);
4055840556 if (nullishSemantics !== PredicateSemantics.Sometimes) {
4055940557 if (nullishSemantics === PredicateSemantics.Always) {
@@ -40565,25 +40563,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4056540563 }
4056640564 }
4056740565
40568- function checkNullishCoalesceOperandRight(node: BinaryExpression) {
40569- const rightTarget = skipOuterExpressions(node.right, OuterExpressionKinds.All);
40570- const nullishSemantics = getSyntacticNullishnessSemantics(rightTarget);
40571- if (isNotWithinNullishCoalesceExpression(node)) {
40572- return;
40573- }
40574-
40575- if (nullishSemantics === PredicateSemantics.Always) {
40576- error(rightTarget, Diagnostics.This_expression_is_always_nullish);
40577- }
40578- else if (nullishSemantics === PredicateSemantics.Never) {
40579- error(rightTarget, Diagnostics.This_expression_is_never_nullish);
40580- }
40581- }
40582-
40583- function isNotWithinNullishCoalesceExpression(node: BinaryExpression) {
40584- return !isBinaryExpression(node.parent) || node.parent.operatorToken.kind !== SyntaxKind.QuestionQuestionToken;
40585- }
40586-
4058740566 function getSyntacticNullishnessSemantics(node: Node): PredicateSemantics {
4058840567 node = skipOuterExpressions(node);
4058940568 switch (node.kind) {
@@ -40601,15 +40580,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4060140580 // List of operators that can produce null/undefined:
4060240581 // = ??= ?? || ||= && &&=
4060340582 switch ((node as BinaryExpression).operatorToken.kind) {
40604- case SyntaxKind.EqualsToken:
40605- case SyntaxKind.QuestionQuestionToken:
40606- case SyntaxKind.QuestionQuestionEqualsToken:
4060740583 case SyntaxKind.BarBarToken:
4060840584 case SyntaxKind.BarBarEqualsToken:
4060940585 case SyntaxKind.AmpersandAmpersandToken:
4061040586 case SyntaxKind.AmpersandAmpersandEqualsToken:
4061140587 return PredicateSemantics.Sometimes;
40588+ // For these operator kinds, the right operand is effectively controlling
4061240589 case SyntaxKind.CommaToken:
40590+ case SyntaxKind.EqualsToken:
40591+ case SyntaxKind.QuestionQuestionToken:
40592+ case SyntaxKind.QuestionQuestionEqualsToken:
4061340593 return getSyntacticNullishnessSemantics((node as BinaryExpression).right);
4061440594 }
4061540595 return PredicateSemantics.Never;
0 commit comments