@@ -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;
@@ -17144,8 +17145,11 @@ namespace ts {
17144
17145
// Assignments only narrow the computed type if the declared type is a union type. Thus, we
17145
17146
// only need to evaluate the assigned type if the declared type is a union type.
17146
17147
if (isMatchingReference(reference, node)) {
17148
+ const flowType = getTypeAtFlowNode(flow.antecedent);
17149
+ if (flowType === unreachableNeverType) {
17150
+ return flowType;
17151
+ }
17147
17152
if (getAssignmentTargetKind(node) === AssignmentKind.Compound) {
17148
- const flowType = getTypeAtFlowNode(flow.antecedent);
17149
17153
return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType));
17150
17154
}
17151
17155
if (declaredType === autoType || declaredType === autoArrayType) {
@@ -17165,12 +17169,16 @@ namespace ts {
17165
17169
// reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case,
17166
17170
// return the declared type.
17167
17171
if (containsMatchingReference(reference, node)) {
17172
+ const flowType = getTypeAtFlowNode(flow.antecedent);
17173
+ if (flowType === unreachableNeverType) {
17174
+ return flowType;
17175
+ }
17168
17176
// A matching dotted name might also be an expando property on a function *expression*,
17169
17177
// in which case we continue control flow analysis back to the function's declaration
17170
17178
if (isVariableDeclaration(node) && (isInJSFile(node) || isVarConst(node))) {
17171
17179
const init = getDeclaredExpandoInitializer(node);
17172
17180
if (init && (init.kind === SyntaxKind.FunctionExpression || init.kind === SyntaxKind.ArrowFunction)) {
17173
- return getTypeAtFlowNode(flow.antecedent) ;
17181
+ return flowType ;
17174
17182
}
17175
17183
}
17176
17184
return declaredType;
@@ -17209,7 +17217,7 @@ namespace ts {
17209
17217
return narrowedType === type ? flowType : createFlowType(narrowedType, isIncomplete(flowType));
17210
17218
}
17211
17219
if (getReturnTypeOfSignature(signature).flags & TypeFlags.Never) {
17212
- return neverType ;
17220
+ return unreachableNeverType ;
17213
17221
}
17214
17222
}
17215
17223
return undefined;
0 commit comments