@@ -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;
@@ -17037,6 +17038,7 @@ namespace ts {
1703717038 if (key) {
1703817039 const id = getFlowNodeId(flow);
1703917040 if (flowAssignmentKeys[id] === key) {
17041+ flowDepth--;
1704017042 return flowAssignmentTypes[id];
1704117043 }
1704217044 }
@@ -17144,8 +17146,11 @@ namespace ts {
1714417146 // Assignments only narrow the computed type if the declared type is a union type. Thus, we
1714517147 // only need to evaluate the assigned type if the declared type is a union type.
1714617148 if (isMatchingReference(reference, node)) {
17149+ const flowType = getTypeAtFlowNode(flow.antecedent);
17150+ if (flowType === unreachableNeverType) {
17151+ return flowType;
17152+ }
1714717153 if (getAssignmentTargetKind(node) === AssignmentKind.Compound) {
17148- const flowType = getTypeAtFlowNode(flow.antecedent);
1714917154 return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType));
1715017155 }
1715117156 if (declaredType === autoType || declaredType === autoArrayType) {
@@ -17165,12 +17170,16 @@ namespace ts {
1716517170 // reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case,
1716617171 // return the declared type.
1716717172 if (containsMatchingReference(reference, node)) {
17173+ const flowType = getTypeAtFlowNode(flow.antecedent);
17174+ if (flowType === unreachableNeverType) {
17175+ return flowType;
17176+ }
1716817177 // A matching dotted name might also be an expando property on a function *expression*,
1716917178 // in which case we continue control flow analysis back to the function's declaration
1717017179 if (isVariableDeclaration(node) && (isInJSFile(node) || isVarConst(node))) {
1717117180 const init = getDeclaredExpandoInitializer(node);
1717217181 if (init && (init.kind === SyntaxKind.FunctionExpression || init.kind === SyntaxKind.ArrowFunction)) {
17173- return getTypeAtFlowNode(flow.antecedent) ;
17182+ return flowType ;
1717417183 }
1717517184 }
1717617185 return declaredType;
@@ -17209,7 +17218,7 @@ namespace ts {
1720917218 return narrowedType === type ? flowType : createFlowType(narrowedType, isIncomplete(flowType));
1721017219 }
1721117220 if (getReturnTypeOfSignature(signature).flags & TypeFlags.Never) {
17212- return neverType ;
17221+ return unreachableNeverType ;
1721317222 }
1721417223 }
1721517224 return undefined;
0 commit comments