@@ -132,6 +132,7 @@ namespace ts {
132132 const esSymbolType = createIntrinsicType(TypeFlags.ESSymbol, "symbol");
133133 const voidType = createIntrinsicType(TypeFlags.Void, "void");
134134 const neverType = createIntrinsicType(TypeFlags.Never, "never");
135+ const silentNeverType = createIntrinsicType(TypeFlags.Never, "never");
135136
136137 const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
137138 const emptyGenericType = <GenericType><ObjectType>createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
@@ -147,6 +148,7 @@ namespace ts {
147148 const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
148149 const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, unknownType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
149150 const resolvingSignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
151+ const silentNeverSignature = createSignature(undefined, undefined, undefined, emptyArray, silentNeverType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
150152
151153 const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
152154
@@ -8073,8 +8075,11 @@ namespace ts {
80738075 // we remove type string.
80748076 function getAssignmentReducedType(declaredType: UnionType, assignedType: Type) {
80758077 if (declaredType !== assignedType) {
8078+ if (assignedType.flags & TypeFlags.Never) {
8079+ return assignedType;
8080+ }
80768081 const reducedType = filterType(declaredType, t => typeMaybeAssignableTo(assignedType, t));
8077- if (reducedType !== neverType ) {
8082+ if (!( reducedType.flags & TypeFlags.Never) ) {
80788083 return reducedType;
80798084 }
80808085 }
@@ -8354,7 +8359,7 @@ namespace ts {
83548359 const visitedFlowStart = visitedFlowCount;
83558360 const result = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode));
83568361 visitedFlowCount = visitedFlowStart;
8357- if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(result, TypeFacts.NEUndefinedOrNull) === neverType ) {
8362+ if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(result, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never ) {
83588363 return declaredType;
83598364 }
83608365 return result;
@@ -8443,17 +8448,18 @@ namespace ts {
84438448 function getTypeAtFlowCondition(flow: FlowCondition): FlowType {
84448449 const flowType = getTypeAtFlowNode(flow.antecedent);
84458450 let type = getTypeFromFlowType(flowType);
8446- if (type !== neverType ) {
8451+ if (!( type.flags & TypeFlags.Never) ) {
84478452 // If we have an antecedent type (meaning we're reachable in some way), we first
84488453 // attempt to narrow the antecedent type. If that produces the never type, and if
84498454 // the antecedent type is incomplete (i.e. a transient type in a loop), then we
84508455 // take the type guard as an indication that control *could* reach here once we
8451- // have the complete type. We proceed by reverting to the declared type and then
8452- // narrow that.
8456+ // have the complete type. We proceed by switching to the silent never type which
8457+ // doesn't report errors when operators are applied to it. Note that this is the
8458+ // *only* place a silent never type is ever generated.
84538459 const assumeTrue = (flow.flags & FlowFlags.TrueCondition) !== 0;
84548460 type = narrowType(type, flow.expression, assumeTrue);
8455- if (type === neverType && isIncomplete(flowType)) {
8456- type = narrowType(declaredType, flow.expression, assumeTrue) ;
8461+ if (type.flags & TypeFlags.Never && isIncomplete(flowType)) {
8462+ type = silentNeverType ;
84578463 }
84588464 }
84598465 return createFlowType(type, isIncomplete(flowType));
@@ -8662,7 +8668,7 @@ namespace ts {
86628668 }
86638669 if (assumeTrue) {
86648670 const narrowedType = filterType(type, t => areTypesComparable(t, valueType));
8665- return narrowedType !== neverType ? narrowedType : type ;
8671+ return narrowedType.flags & TypeFlags.Never ? type : narrowedType ;
86668672 }
86678673 return isUnitType(valueType) ? filterType(type, t => t !== valueType) : type;
86688674 }
@@ -8705,12 +8711,12 @@ namespace ts {
87058711 const clauseTypes = switchTypes.slice(clauseStart, clauseEnd);
87068712 const hasDefaultClause = clauseStart === clauseEnd || contains(clauseTypes, neverType);
87078713 const discriminantType = getUnionType(clauseTypes);
8708- const caseType = discriminantType === neverType ? neverType : filterType(type, t => isTypeComparableTo(discriminantType, t));
8714+ const caseType = discriminantType.flags & TypeFlags.Never ? neverType : filterType(type, t => isTypeComparableTo(discriminantType, t));
87098715 if (!hasDefaultClause) {
87108716 return caseType;
87118717 }
87128718 const defaultType = filterType(type, t => !(isUnitType(t) && contains(switchTypes, t)));
8713- return caseType === neverType ? defaultType : getUnionType([caseType, defaultType]);
8719+ return caseType.flags & TypeFlags.Never ? defaultType : getUnionType([caseType, defaultType]);
87148720 }
87158721
87168722 function narrowTypeByInstanceof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
@@ -8774,7 +8780,7 @@ namespace ts {
87748780 // the candidate type. If one or more constituents remain, return a union of those.
87758781 if (type.flags & TypeFlags.Union) {
87768782 const assignableType = filterType(type, t => isTypeInstanceOf(t, candidate));
8777- if (assignableType !== neverType ) {
8783+ if (!( assignableType.flags & TypeFlags.Never) ) {
87788784 return assignableType;
87798785 }
87808786 }
@@ -10892,7 +10898,7 @@ namespace ts {
1089210898
1089310899 function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) {
1089410900 const type = checkNonNullExpression(left);
10895- if (isTypeAny(type)) {
10901+ if (isTypeAny(type) || type === silentNeverType ) {
1089610902 return type;
1089710903 }
1089810904
@@ -11039,8 +11045,8 @@ namespace ts {
1103911045 const objectType = getApparentType(checkNonNullExpression(node.expression));
1104011046 const indexType = node.argumentExpression ? checkExpression(node.argumentExpression) : unknownType;
1104111047
11042- if (objectType === unknownType) {
11043- return unknownType ;
11048+ if (objectType === unknownType || objectType === silentNeverType ) {
11049+ return objectType ;
1104411050 }
1104511051
1104611052 const isConstEnum = isConstEnumObjectType(objectType);
@@ -12090,6 +12096,9 @@ namespace ts {
1209012096 }
1209112097
1209212098 const funcType = checkNonNullExpression(node.expression);
12099+ if (funcType === silentNeverType) {
12100+ return silentNeverSignature;
12101+ }
1209312102 const apparentType = getApparentType(funcType);
1209412103
1209512104 if (apparentType === unknownType) {
@@ -12162,6 +12171,9 @@ namespace ts {
1216212171 }
1216312172
1216412173 let expressionType = checkNonNullExpression(node.expression);
12174+ if (expressionType === silentNeverType) {
12175+ return silentNeverSignature;
12176+ }
1216512177
1216612178 // If expressionType's apparent type(section 3.8.1) is an object type with one or
1216712179 // more construct signatures, the expression is processed in the same manner as a
@@ -12721,7 +12733,7 @@ namespace ts {
1272112733 // the native Promise<T> type by the caller.
1272212734 type = checkAwaitedType(type, func, Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member);
1272312735 }
12724- if (type === neverType ) {
12736+ if (type.flags & TypeFlags.Never ) {
1272512737 hasReturnOfTypeNever = true;
1272612738 }
1272712739 else if (!contains(aggregatedTypes, type)) {
@@ -12771,7 +12783,7 @@ namespace ts {
1277112783
1277212784 const hasExplicitReturn = func.flags & NodeFlags.HasExplicitReturn;
1277312785
12774- if (returnType === neverType ) {
12786+ if (returnType && returnType.flags & TypeFlags.Never ) {
1277512787 error(func.type, Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point);
1277612788 }
1277712789 else if (returnType && !hasExplicitReturn) {
@@ -13027,6 +13039,9 @@ namespace ts {
1302713039
1302813040 function checkPrefixUnaryExpression(node: PrefixUnaryExpression): Type {
1302913041 const operandType = checkExpression(node.operand);
13042+ if (operandType === silentNeverType) {
13043+ return silentNeverType;
13044+ }
1303013045 if (node.operator === SyntaxKind.MinusToken && node.operand.kind === SyntaxKind.NumericLiteral) {
1303113046 return getLiteralTypeForText(TypeFlags.NumberLiteral, "" + -(<LiteralExpression>node.operand).text);
1303213047 }
@@ -13060,6 +13075,9 @@ namespace ts {
1306013075
1306113076 function checkPostfixUnaryExpression(node: PostfixUnaryExpression): Type {
1306213077 const operandType = checkExpression(node.operand);
13078+ if (operandType === silentNeverType) {
13079+ return silentNeverType;
13080+ }
1306313081 const ok = checkArithmeticOperandType(node.operand, getNonNullableType(operandType),
1306413082 Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type);
1306513083 if (ok) {
@@ -13124,6 +13142,9 @@ namespace ts {
1312413142 }
1312513143
1312613144 function checkInstanceOfExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type {
13145+ if (leftType === silentNeverType || rightType === silentNeverType) {
13146+ return silentNeverType;
13147+ }
1312713148 // TypeScript 1.0 spec (April 2014): 4.15.4
1312813149 // The instanceof operator requires the left operand to be of type Any, an object type, or a type parameter type,
1312913150 // and the right operand to be of type Any or a subtype of the 'Function' interface type.
@@ -13140,6 +13161,9 @@ namespace ts {
1314013161 }
1314113162
1314213163 function checkInExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type {
13164+ if (leftType === silentNeverType || rightType === silentNeverType) {
13165+ return silentNeverType;
13166+ }
1314313167 // TypeScript 1.0 spec (April 2014): 4.15.5
1314413168 // The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
1314513169 // and the right operand to be of type Any, an object type, or a type parameter type.
@@ -13404,6 +13428,9 @@ namespace ts {
1340413428 case SyntaxKind.CaretEqualsToken:
1340513429 case SyntaxKind.AmpersandToken:
1340613430 case SyntaxKind.AmpersandEqualsToken:
13431+ if (leftType === silentNeverType || rightType === silentNeverType) {
13432+ return silentNeverType;
13433+ }
1340713434 // TypeScript 1.0 spec (April 2014): 4.19.1
1340813435 // These operators require their operands to be of type Any, the Number primitive type,
1340913436 // or an enum type. Operands of an enum type are treated
@@ -13436,6 +13463,9 @@ namespace ts {
1343613463 return numberType;
1343713464 case SyntaxKind.PlusToken:
1343813465 case SyntaxKind.PlusEqualsToken:
13466+ if (leftType === silentNeverType || rightType === silentNeverType) {
13467+ return silentNeverType;
13468+ }
1343913469 // TypeScript 1.0 spec (April 2014): 4.19.2
1344013470 // The binary + operator requires both operands to be of the Number primitive type or an enum type,
1344113471 // or at least one of the operands to be of type Any or the String primitive type.
@@ -16268,7 +16298,7 @@ namespace ts {
1626816298
1626916299 // Now that we've removed all the StringLike types, if no constituents remain, then the entire
1627016300 // arrayOrStringType was a string.
16271- if (arrayType === neverType ) {
16301+ if (arrayType.flags & TypeFlags.Never ) {
1627216302 return stringType;
1627316303 }
1627416304 }
@@ -16329,7 +16359,7 @@ namespace ts {
1632916359 if (func) {
1633016360 const signature = getSignatureFromDeclaration(func);
1633116361 const returnType = getReturnTypeOfSignature(signature);
16332- if (strictNullChecks || node.expression || returnType === neverType ) {
16362+ if (strictNullChecks || node.expression || returnType.flags & TypeFlags.Never ) {
1633316363 const exprType = node.expression ? checkExpressionCached(node.expression) : undefinedType;
1633416364
1633516365 if (func.asteriskToken) {
0 commit comments