@@ -671,6 +671,7 @@ namespace ts {
671671 const silentNeverType = createIntrinsicType(TypeFlags.Never, "never");
672672 const nonInferrableType = createIntrinsicType(TypeFlags.Never, "never", ObjectFlags.NonInferrableType);
673673 const implicitNeverType = createIntrinsicType(TypeFlags.Never, "never");
674+ const unreachableNeverType = createIntrinsicType(TypeFlags.Never, "never");
674675 const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object");
675676 const stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]);
676677 const keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType;
@@ -17008,7 +17009,7 @@ namespace ts {
1700817009 // on empty arrays are possible without implicit any errors and new element types can be inferred without
1700917010 // type mismatch errors.
1701017011 const resultType = getObjectFlags(evolvedType) & ObjectFlags.EvolvingArray && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType);
17011- if (reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) {
17012+ if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) {
1701217013 return declaredType;
1701317014 }
1701417015 return resultType;
@@ -17144,8 +17145,11 @@ namespace ts {
1714417145 // Assignments only narrow the computed type if the declared type is a union type. Thus, we
1714517146 // only need to evaluate the assigned type if the declared type is a union type.
1714617147 if (isMatchingReference(reference, node)) {
17148+ const flowType = getTypeAtFlowNode(flow.antecedent);
17149+ if (flowType === unreachableNeverType) {
17150+ return flowType;
17151+ }
1714717152 if (getAssignmentTargetKind(node) === AssignmentKind.Compound) {
17148- const flowType = getTypeAtFlowNode(flow.antecedent);
1714917153 return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType));
1715017154 }
1715117155 if (declaredType === autoType || declaredType === autoArrayType) {
@@ -17165,12 +17169,16 @@ namespace ts {
1716517169 // reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case,
1716617170 // return the declared type.
1716717171 if (containsMatchingReference(reference, node)) {
17172+ const flowType = getTypeAtFlowNode(flow.antecedent);
17173+ if (flowType === unreachableNeverType) {
17174+ return flowType;
17175+ }
1716817176 // A matching dotted name might also be an expando property on a function *expression*,
1716917177 // in which case we continue control flow analysis back to the function's declaration
1717017178 if (isVariableDeclaration(node) && (isInJSFile(node) || isVarConst(node))) {
1717117179 const init = getDeclaredExpandoInitializer(node);
1717217180 if (init && (init.kind === SyntaxKind.FunctionExpression || init.kind === SyntaxKind.ArrowFunction)) {
17173- return getTypeAtFlowNode(flow.antecedent) ;
17181+ return flowType ;
1717417182 }
1717517183 }
1717617184 return declaredType;
@@ -17209,7 +17217,7 @@ namespace ts {
1720917217 return narrowedType === type ? flowType : createFlowType(narrowedType, isIncomplete(flowType));
1721017218 }
1721117219 if (getReturnTypeOfSignature(signature).flags & TypeFlags.Never) {
17212- return neverType ;
17220+ return unreachableNeverType ;
1721317221 }
1721417222 }
1721517223 return undefined;
0 commit comments