@@ -671,6 +671,7 @@ namespace ts {
671
671
const silentNeverType = createIntrinsicType(TypeFlags.Never, "never");
672
672
const nonInferrableType = createIntrinsicType(TypeFlags.Never, "never", ObjectFlags.NonInferrableType);
673
673
const implicitNeverType = createIntrinsicType(TypeFlags.Never, "never");
674
+ const unreachableNeverType = createIntrinsicType(TypeFlags.Never, "never");
674
675
const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object");
675
676
const stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]);
676
677
const keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType;
@@ -17008,7 +17009,7 @@ namespace ts {
17008
17009
// on empty arrays are possible without implicit any errors and new element types can be inferred without
17009
17010
// type mismatch errors.
17010
17011
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) {
17012
17013
return declaredType;
17013
17014
}
17014
17015
return resultType;
@@ -17037,6 +17038,7 @@ namespace ts {
17037
17038
if (key) {
17038
17039
const id = getFlowNodeId(flow);
17039
17040
if (flowAssignmentKeys[id] === key) {
17041
+ flowDepth--;
17040
17042
return flowAssignmentTypes[id];
17041
17043
}
17042
17044
}
@@ -17144,8 +17146,11 @@ namespace ts {
17144
17146
// Assignments only narrow the computed type if the declared type is a union type. Thus, we
17145
17147
// only need to evaluate the assigned type if the declared type is a union type.
17146
17148
if (isMatchingReference(reference, node)) {
17149
+ const flowType = getTypeAtFlowNode(flow.antecedent);
17150
+ if (flowType === unreachableNeverType) {
17151
+ return flowType;
17152
+ }
17147
17153
if (getAssignmentTargetKind(node) === AssignmentKind.Compound) {
17148
- const flowType = getTypeAtFlowNode(flow.antecedent);
17149
17154
return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType));
17150
17155
}
17151
17156
if (declaredType === autoType || declaredType === autoArrayType) {
@@ -17165,12 +17170,16 @@ namespace ts {
17165
17170
// reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case,
17166
17171
// return the declared type.
17167
17172
if (containsMatchingReference(reference, node)) {
17173
+ const flowType = getTypeAtFlowNode(flow.antecedent);
17174
+ if (flowType === unreachableNeverType) {
17175
+ return flowType;
17176
+ }
17168
17177
// A matching dotted name might also be an expando property on a function *expression*,
17169
17178
// in which case we continue control flow analysis back to the function's declaration
17170
17179
if (isVariableDeclaration(node) && (isInJSFile(node) || isVarConst(node))) {
17171
17180
const init = getDeclaredExpandoInitializer(node);
17172
17181
if (init && (init.kind === SyntaxKind.FunctionExpression || init.kind === SyntaxKind.ArrowFunction)) {
17173
- return getTypeAtFlowNode(flow.antecedent) ;
17182
+ return flowType ;
17174
17183
}
17175
17184
}
17176
17185
return declaredType;
@@ -17209,7 +17218,7 @@ namespace ts {
17209
17218
return narrowedType === type ? flowType : createFlowType(narrowedType, isIncomplete(flowType));
17210
17219
}
17211
17220
if (getReturnTypeOfSignature(signature).flags & TypeFlags.Never) {
17212
- return neverType ;
17221
+ return unreachableNeverType ;
17213
17222
}
17214
17223
}
17215
17224
return undefined;
0 commit comments