@@ -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
@@ -8070,6 +8072,9 @@ namespace ts {
8070
8072
// we remove type string.
8071
8073
function getAssignmentReducedType(declaredType: UnionType, assignedType: Type) {
8072
8074
if (declaredType !== assignedType) {
8075
+ if (assignedType.flags & TypeFlags.Never) {
8076
+ return assignedType;
8077
+ }
8073
8078
const reducedType = filterType(declaredType, t => typeMaybeAssignableTo(assignedType, t));
8074
8079
if (!(reducedType.flags & TypeFlags.Never)) {
8075
8080
return reducedType;
@@ -8445,12 +8450,13 @@ namespace ts {
8445
8450
// attempt to narrow the antecedent type. If that produces the never type, and if
8446
8451
// the antecedent type is incomplete (i.e. a transient type in a loop), then we
8447
8452
// take the type guard as an indication that control *could* reach here once we
8448
- // have the complete type. We proceed by reverting to the declared type and then
8449
- // narrow that.
8453
+ // have the complete type. We proceed by switching to the silent never type which
8454
+ // doesn't report errors when operators are applied to it. Note that this is the
8455
+ // *only* place a silent never type is ever generated.
8450
8456
const assumeTrue = (flow.flags & FlowFlags.TrueCondition) !== 0;
8451
8457
type = narrowType(type, flow.expression, assumeTrue);
8452
8458
if (type.flags & TypeFlags.Never && isIncomplete(flowType)) {
8453
- type = narrowType(declaredType, flow.expression, assumeTrue) ;
8459
+ type = silentNeverType ;
8454
8460
}
8455
8461
}
8456
8462
return createFlowType(type, isIncomplete(flowType));
@@ -10889,7 +10895,7 @@ namespace ts {
10889
10895
10890
10896
function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) {
10891
10897
const type = checkNonNullExpression(left);
10892
- if (isTypeAny(type)) {
10898
+ if (isTypeAny(type) || type === silentNeverType ) {
10893
10899
return type;
10894
10900
}
10895
10901
@@ -11036,8 +11042,8 @@ namespace ts {
11036
11042
const objectType = getApparentType(checkNonNullExpression(node.expression));
11037
11043
const indexType = node.argumentExpression ? checkExpression(node.argumentExpression) : unknownType;
11038
11044
11039
- if (objectType === unknownType) {
11040
- return unknownType ;
11045
+ if (objectType === unknownType || objectType === silentNeverType ) {
11046
+ return objectType ;
11041
11047
}
11042
11048
11043
11049
const isConstEnum = isConstEnumObjectType(objectType);
@@ -12087,6 +12093,9 @@ namespace ts {
12087
12093
}
12088
12094
12089
12095
const funcType = checkNonNullExpression(node.expression);
12096
+ if (funcType === silentNeverType) {
12097
+ return silentNeverSignature;
12098
+ }
12090
12099
const apparentType = getApparentType(funcType);
12091
12100
12092
12101
if (apparentType === unknownType) {
@@ -12159,6 +12168,9 @@ namespace ts {
12159
12168
}
12160
12169
12161
12170
let expressionType = checkNonNullExpression(node.expression);
12171
+ if (expressionType === silentNeverType) {
12172
+ return silentNeverSignature;
12173
+ }
12162
12174
12163
12175
// If expressionType's apparent type(section 3.8.1) is an object type with one or
12164
12176
// more construct signatures, the expression is processed in the same manner as a
@@ -13024,6 +13036,9 @@ namespace ts {
13024
13036
13025
13037
function checkPrefixUnaryExpression(node: PrefixUnaryExpression): Type {
13026
13038
const operandType = checkExpression(node.operand);
13039
+ if (operandType === silentNeverType) {
13040
+ return silentNeverType;
13041
+ }
13027
13042
if (node.operator === SyntaxKind.MinusToken && node.operand.kind === SyntaxKind.NumericLiteral) {
13028
13043
return getLiteralTypeForText(TypeFlags.NumberLiteral, "" + -(<LiteralExpression>node.operand).text);
13029
13044
}
@@ -13057,6 +13072,9 @@ namespace ts {
13057
13072
13058
13073
function checkPostfixUnaryExpression(node: PostfixUnaryExpression): Type {
13059
13074
const operandType = checkExpression(node.operand);
13075
+ if (operandType === silentNeverType) {
13076
+ return silentNeverType;
13077
+ }
13060
13078
const ok = checkArithmeticOperandType(node.operand, getNonNullableType(operandType),
13061
13079
Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type);
13062
13080
if (ok) {
@@ -13121,6 +13139,9 @@ namespace ts {
13121
13139
}
13122
13140
13123
13141
function checkInstanceOfExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type {
13142
+ if (leftType === silentNeverType || rightType === silentNeverType) {
13143
+ return silentNeverType;
13144
+ }
13124
13145
// TypeScript 1.0 spec (April 2014): 4.15.4
13125
13146
// The instanceof operator requires the left operand to be of type Any, an object type, or a type parameter type,
13126
13147
// and the right operand to be of type Any or a subtype of the 'Function' interface type.
@@ -13137,6 +13158,9 @@ namespace ts {
13137
13158
}
13138
13159
13139
13160
function checkInExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type {
13161
+ if (leftType === silentNeverType || rightType === silentNeverType) {
13162
+ return silentNeverType;
13163
+ }
13140
13164
// TypeScript 1.0 spec (April 2014): 4.15.5
13141
13165
// The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
13142
13166
// and the right operand to be of type Any, an object type, or a type parameter type.
@@ -13401,6 +13425,9 @@ namespace ts {
13401
13425
case SyntaxKind.CaretEqualsToken:
13402
13426
case SyntaxKind.AmpersandToken:
13403
13427
case SyntaxKind.AmpersandEqualsToken:
13428
+ if (leftType === silentNeverType || rightType === silentNeverType) {
13429
+ return silentNeverType;
13430
+ }
13404
13431
// TypeScript 1.0 spec (April 2014): 4.19.1
13405
13432
// These operators require their operands to be of type Any, the Number primitive type,
13406
13433
// or an enum type. Operands of an enum type are treated
@@ -13433,6 +13460,9 @@ namespace ts {
13433
13460
return numberType;
13434
13461
case SyntaxKind.PlusToken:
13435
13462
case SyntaxKind.PlusEqualsToken:
13463
+ if (leftType === silentNeverType || rightType === silentNeverType) {
13464
+ return silentNeverType;
13465
+ }
13436
13466
// TypeScript 1.0 spec (April 2014): 4.19.2
13437
13467
// The binary + operator requires both operands to be of the Number primitive type or an enum type,
13438
13468
// or at least one of the operands to be of type Any or the String primitive type.
0 commit comments