@@ -132,6 +132,7 @@ namespace ts {
132
132
const esSymbolType = createIntrinsicType(TypeFlags.ESSymbol, "symbol");
133
133
const voidType = createIntrinsicType(TypeFlags.Void, "void");
134
134
const neverType = createIntrinsicType(TypeFlags.Never, "never");
135
+ const silentNeverType = createIntrinsicType(TypeFlags.Never, "never");
135
136
136
137
const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
137
138
const emptyGenericType = <GenericType><ObjectType>createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
@@ -147,6 +148,7 @@ namespace ts {
147
148
const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
148
149
const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, unknownType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
149
150
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);
150
152
151
153
const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
152
154
@@ -8073,8 +8075,11 @@ namespace ts {
8073
8075
// we remove type string.
8074
8076
function getAssignmentReducedType(declaredType: UnionType, assignedType: Type) {
8075
8077
if (declaredType !== assignedType) {
8078
+ if (assignedType.flags & TypeFlags.Never) {
8079
+ return assignedType;
8080
+ }
8076
8081
const reducedType = filterType(declaredType, t => typeMaybeAssignableTo(assignedType, t));
8077
- if (reducedType !== neverType ) {
8082
+ if (!( reducedType.flags & TypeFlags.Never) ) {
8078
8083
return reducedType;
8079
8084
}
8080
8085
}
@@ -8354,7 +8359,7 @@ namespace ts {
8354
8359
const visitedFlowStart = visitedFlowCount;
8355
8360
const result = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode));
8356
8361
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 ) {
8358
8363
return declaredType;
8359
8364
}
8360
8365
return result;
@@ -8443,17 +8448,18 @@ namespace ts {
8443
8448
function getTypeAtFlowCondition(flow: FlowCondition): FlowType {
8444
8449
const flowType = getTypeAtFlowNode(flow.antecedent);
8445
8450
let type = getTypeFromFlowType(flowType);
8446
- if (type !== neverType ) {
8451
+ if (!( type.flags & TypeFlags.Never) ) {
8447
8452
// If we have an antecedent type (meaning we're reachable in some way), we first
8448
8453
// attempt to narrow the antecedent type. If that produces the never type, and if
8449
8454
// the antecedent type is incomplete (i.e. a transient type in a loop), then we
8450
8455
// 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.
8453
8459
const assumeTrue = (flow.flags & FlowFlags.TrueCondition) !== 0;
8454
8460
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 ;
8457
8463
}
8458
8464
}
8459
8465
return createFlowType(type, isIncomplete(flowType));
@@ -8662,7 +8668,7 @@ namespace ts {
8662
8668
}
8663
8669
if (assumeTrue) {
8664
8670
const narrowedType = filterType(type, t => areTypesComparable(t, valueType));
8665
- return narrowedType !== neverType ? narrowedType : type ;
8671
+ return narrowedType.flags & TypeFlags.Never ? type : narrowedType ;
8666
8672
}
8667
8673
return isUnitType(valueType) ? filterType(type, t => t !== valueType) : type;
8668
8674
}
@@ -8705,12 +8711,12 @@ namespace ts {
8705
8711
const clauseTypes = switchTypes.slice(clauseStart, clauseEnd);
8706
8712
const hasDefaultClause = clauseStart === clauseEnd || contains(clauseTypes, neverType);
8707
8713
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));
8709
8715
if (!hasDefaultClause) {
8710
8716
return caseType;
8711
8717
}
8712
8718
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]);
8714
8720
}
8715
8721
8716
8722
function narrowTypeByInstanceof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
@@ -8774,7 +8780,7 @@ namespace ts {
8774
8780
// the candidate type. If one or more constituents remain, return a union of those.
8775
8781
if (type.flags & TypeFlags.Union) {
8776
8782
const assignableType = filterType(type, t => isTypeInstanceOf(t, candidate));
8777
- if (assignableType !== neverType ) {
8783
+ if (!( assignableType.flags & TypeFlags.Never) ) {
8778
8784
return assignableType;
8779
8785
}
8780
8786
}
@@ -10892,7 +10898,7 @@ namespace ts {
10892
10898
10893
10899
function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) {
10894
10900
const type = checkNonNullExpression(left);
10895
- if (isTypeAny(type)) {
10901
+ if (isTypeAny(type) || type === silentNeverType ) {
10896
10902
return type;
10897
10903
}
10898
10904
@@ -11039,8 +11045,8 @@ namespace ts {
11039
11045
const objectType = getApparentType(checkNonNullExpression(node.expression));
11040
11046
const indexType = node.argumentExpression ? checkExpression(node.argumentExpression) : unknownType;
11041
11047
11042
- if (objectType === unknownType) {
11043
- return unknownType ;
11048
+ if (objectType === unknownType || objectType === silentNeverType ) {
11049
+ return objectType ;
11044
11050
}
11045
11051
11046
11052
const isConstEnum = isConstEnumObjectType(objectType);
@@ -12090,6 +12096,9 @@ namespace ts {
12090
12096
}
12091
12097
12092
12098
const funcType = checkNonNullExpression(node.expression);
12099
+ if (funcType === silentNeverType) {
12100
+ return silentNeverSignature;
12101
+ }
12093
12102
const apparentType = getApparentType(funcType);
12094
12103
12095
12104
if (apparentType === unknownType) {
@@ -12162,6 +12171,9 @@ namespace ts {
12162
12171
}
12163
12172
12164
12173
let expressionType = checkNonNullExpression(node.expression);
12174
+ if (expressionType === silentNeverType) {
12175
+ return silentNeverSignature;
12176
+ }
12165
12177
12166
12178
// If expressionType's apparent type(section 3.8.1) is an object type with one or
12167
12179
// more construct signatures, the expression is processed in the same manner as a
@@ -12721,7 +12733,7 @@ namespace ts {
12721
12733
// the native Promise<T> type by the caller.
12722
12734
type = checkAwaitedType(type, func, Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member);
12723
12735
}
12724
- if (type === neverType ) {
12736
+ if (type.flags & TypeFlags.Never ) {
12725
12737
hasReturnOfTypeNever = true;
12726
12738
}
12727
12739
else if (!contains(aggregatedTypes, type)) {
@@ -12771,7 +12783,7 @@ namespace ts {
12771
12783
12772
12784
const hasExplicitReturn = func.flags & NodeFlags.HasExplicitReturn;
12773
12785
12774
- if (returnType === neverType ) {
12786
+ if (returnType && returnType.flags & TypeFlags.Never ) {
12775
12787
error(func.type, Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point);
12776
12788
}
12777
12789
else if (returnType && !hasExplicitReturn) {
@@ -13027,6 +13039,9 @@ namespace ts {
13027
13039
13028
13040
function checkPrefixUnaryExpression(node: PrefixUnaryExpression): Type {
13029
13041
const operandType = checkExpression(node.operand);
13042
+ if (operandType === silentNeverType) {
13043
+ return silentNeverType;
13044
+ }
13030
13045
if (node.operator === SyntaxKind.MinusToken && node.operand.kind === SyntaxKind.NumericLiteral) {
13031
13046
return getLiteralTypeForText(TypeFlags.NumberLiteral, "" + -(<LiteralExpression>node.operand).text);
13032
13047
}
@@ -13060,6 +13075,9 @@ namespace ts {
13060
13075
13061
13076
function checkPostfixUnaryExpression(node: PostfixUnaryExpression): Type {
13062
13077
const operandType = checkExpression(node.operand);
13078
+ if (operandType === silentNeverType) {
13079
+ return silentNeverType;
13080
+ }
13063
13081
const ok = checkArithmeticOperandType(node.operand, getNonNullableType(operandType),
13064
13082
Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type);
13065
13083
if (ok) {
@@ -13124,6 +13142,9 @@ namespace ts {
13124
13142
}
13125
13143
13126
13144
function checkInstanceOfExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type {
13145
+ if (leftType === silentNeverType || rightType === silentNeverType) {
13146
+ return silentNeverType;
13147
+ }
13127
13148
// TypeScript 1.0 spec (April 2014): 4.15.4
13128
13149
// The instanceof operator requires the left operand to be of type Any, an object type, or a type parameter type,
13129
13150
// and the right operand to be of type Any or a subtype of the 'Function' interface type.
@@ -13140,6 +13161,9 @@ namespace ts {
13140
13161
}
13141
13162
13142
13163
function checkInExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type {
13164
+ if (leftType === silentNeverType || rightType === silentNeverType) {
13165
+ return silentNeverType;
13166
+ }
13143
13167
// TypeScript 1.0 spec (April 2014): 4.15.5
13144
13168
// The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
13145
13169
// and the right operand to be of type Any, an object type, or a type parameter type.
@@ -13404,6 +13428,9 @@ namespace ts {
13404
13428
case SyntaxKind.CaretEqualsToken:
13405
13429
case SyntaxKind.AmpersandToken:
13406
13430
case SyntaxKind.AmpersandEqualsToken:
13431
+ if (leftType === silentNeverType || rightType === silentNeverType) {
13432
+ return silentNeverType;
13433
+ }
13407
13434
// TypeScript 1.0 spec (April 2014): 4.19.1
13408
13435
// These operators require their operands to be of type Any, the Number primitive type,
13409
13436
// or an enum type. Operands of an enum type are treated
@@ -13436,6 +13463,9 @@ namespace ts {
13436
13463
return numberType;
13437
13464
case SyntaxKind.PlusToken:
13438
13465
case SyntaxKind.PlusEqualsToken:
13466
+ if (leftType === silentNeverType || rightType === silentNeverType) {
13467
+ return silentNeverType;
13468
+ }
13439
13469
// TypeScript 1.0 spec (April 2014): 4.19.2
13440
13470
// The binary + operator requires both operands to be of the Number primitive type or an enum type,
13441
13471
// or at least one of the operands to be of type Any or the String primitive type.
@@ -16268,7 +16298,7 @@ namespace ts {
16268
16298
16269
16299
// Now that we've removed all the StringLike types, if no constituents remain, then the entire
16270
16300
// arrayOrStringType was a string.
16271
- if (arrayType === neverType ) {
16301
+ if (arrayType.flags & TypeFlags.Never ) {
16272
16302
return stringType;
16273
16303
}
16274
16304
}
@@ -16329,7 +16359,7 @@ namespace ts {
16329
16359
if (func) {
16330
16360
const signature = getSignatureFromDeclaration(func);
16331
16361
const returnType = getReturnTypeOfSignature(signature);
16332
- if (strictNullChecks || node.expression || returnType === neverType ) {
16362
+ if (strictNullChecks || node.expression || returnType.flags & TypeFlags.Never ) {
16333
16363
const exprType = node.expression ? checkExpressionCached(node.expression) : undefinedType;
16334
16364
16335
16365
if (func.asteriskToken) {
0 commit comments