@@ -3943,7 +3943,7 @@ namespace ts {
3943
3943
let id = getTypeListId(elementTypes);
3944
3944
let type = tupleTypes[id];
3945
3945
if (!type) {
3946
- type = tupleTypes[id] = <TupleType>createObjectType(TypeFlags.Tuple);
3946
+ type = tupleTypes[id] = <TupleType>createObjectType(TypeFlags.Tuple | getWideningFlagsOfTypes(elementTypes) );
3947
3947
type.elementTypes = elementTypes;
3948
3948
}
3949
3949
return type;
@@ -4906,9 +4906,38 @@ namespace ts {
4906
4906
let targetSignatures = getSignaturesOfType(target, kind);
4907
4907
let result = Ternary.True;
4908
4908
let saveErrorInfo = errorInfo;
4909
+
4910
+ // Because the "abstractness" of a class is the same across all construct signatures
4911
+ // (internally we are checking the corresponding declaration), it is enough to perform
4912
+ // the check and report an error once over all pairs of source and target construct signatures.
4913
+ let sourceSig = sourceSignatures[0];
4914
+ // Note that in an extends-clause, targetSignatures is stripped, so the check never proceeds.
4915
+ let targetSig = targetSignatures[0];
4916
+
4917
+ if (sourceSig && targetSig) {
4918
+ let sourceErasedSignature = getErasedSignature(sourceSig);
4919
+ let targetErasedSignature = getErasedSignature(targetSig);
4920
+
4921
+ let sourceReturnType = sourceErasedSignature && getReturnTypeOfSignature(sourceErasedSignature);
4922
+ let targetReturnType = targetErasedSignature && getReturnTypeOfSignature(targetErasedSignature);
4923
+
4924
+ let sourceReturnDecl = sourceReturnType && sourceReturnType.symbol && getDeclarationOfKind(sourceReturnType.symbol, SyntaxKind.ClassDeclaration);
4925
+ let targetReturnDecl = targetReturnType && targetReturnType.symbol && getDeclarationOfKind(targetReturnType.symbol, SyntaxKind.ClassDeclaration);
4926
+ let sourceIsAbstract = sourceReturnDecl && sourceReturnDecl.flags & NodeFlags.Abstract;
4927
+ let targetIsAbstract = targetReturnDecl && targetReturnDecl.flags & NodeFlags.Abstract;
4928
+
4929
+ if (sourceIsAbstract && !targetIsAbstract) {
4930
+ if (reportErrors) {
4931
+ reportError(Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type);
4932
+ }
4933
+ return Ternary.False;
4934
+ }
4935
+ }
4936
+
4909
4937
outer: for (let t of targetSignatures) {
4910
4938
if (!t.hasStringLiterals || target.flags & TypeFlags.FromSignature) {
4911
4939
let localErrors = reportErrors;
4940
+ let checkedAbstractAssignability = false;
4912
4941
for (let s of sourceSignatures) {
4913
4942
if (!s.hasStringLiterals || source.flags & TypeFlags.FromSignature) {
4914
4943
let related = signatureRelatedTo(s, t, localErrors);
@@ -5015,10 +5044,11 @@ namespace ts {
5015
5044
return Ternary.False;
5016
5045
}
5017
5046
5018
- let t = getReturnTypeOfSignature(target);
5019
- if (t === voidType) return result;
5020
- let s = getReturnTypeOfSignature(source);
5021
- return result & isRelatedTo(s, t, reportErrors);
5047
+ let targetReturnType = getReturnTypeOfSignature(target);
5048
+ if (targetReturnType === voidType) return result;
5049
+ let sourceReturnType = getReturnTypeOfSignature(source);
5050
+
5051
+ return result & isRelatedTo(sourceReturnType, targetReturnType, reportErrors);
5022
5052
}
5023
5053
5024
5054
function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary {
@@ -5272,8 +5302,8 @@ namespace ts {
5272
5302
* Check if a Type was written as a tuple type literal.
5273
5303
* Prefer using isTupleLikeType() unless the use of `elementTypes` is required.
5274
5304
*/
5275
- function isTupleType(type: Type): boolean {
5276
- return (type.flags & TypeFlags.Tuple) && !!(<TupleType>type).elementTypes ;
5305
+ function isTupleType(type: Type): type is TupleType {
5306
+ return !! (type.flags & TypeFlags.Tuple);
5277
5307
}
5278
5308
5279
5309
function getWidenedTypeOfObjectLiteral(type: Type): Type {
@@ -5314,37 +5344,55 @@ namespace ts {
5314
5344
if (isArrayType(type)) {
5315
5345
return createArrayType(getWidenedType((<TypeReference>type).typeArguments[0]));
5316
5346
}
5347
+ if (isTupleType(type)) {
5348
+ return createTupleType(map(type.elementTypes, getWidenedType));
5349
+ }
5317
5350
}
5318
5351
return type;
5319
5352
}
5320
5353
5354
+ /**
5355
+ * Reports implicit any errors that occur as a result of widening 'null' and 'undefined'
5356
+ * to 'any'. A call to reportWideningErrorsInType is normally accompanied by a call to
5357
+ * getWidenedType. But in some cases getWidenedType is called without reporting errors
5358
+ * (type argument inference is an example).
5359
+ *
5360
+ * The return value indicates whether an error was in fact reported. The particular circumstances
5361
+ * are on a best effort basis. Currently, if the null or undefined that causes widening is inside
5362
+ * an object literal property (arbitrarily deeply), this function reports an error. If no error is
5363
+ * reported, reportImplicitAnyError is a suitable fallback to report a general error.
5364
+ */
5321
5365
function reportWideningErrorsInType(type: Type): boolean {
5366
+ let errorReported = false;
5322
5367
if (type.flags & TypeFlags.Union) {
5323
- let errorReported = false;
5324
- forEach((<UnionType>type).types, t => {
5368
+ for (let t of (<UnionType>type).types) {
5325
5369
if (reportWideningErrorsInType(t)) {
5326
5370
errorReported = true;
5327
5371
}
5328
- });
5329
- return errorReported;
5372
+ }
5330
5373
}
5331
5374
if (isArrayType(type)) {
5332
5375
return reportWideningErrorsInType((<TypeReference>type).typeArguments[0]);
5333
5376
}
5377
+ if (isTupleType(type)) {
5378
+ for (let t of type.elementTypes) {
5379
+ if (reportWideningErrorsInType(t)) {
5380
+ errorReported = true;
5381
+ }
5382
+ }
5383
+ }
5334
5384
if (type.flags & TypeFlags.ObjectLiteral) {
5335
- let errorReported = false;
5336
- forEach(getPropertiesOfObjectType(type), p => {
5385
+ for (let p of getPropertiesOfObjectType(type)) {
5337
5386
let t = getTypeOfSymbol(p);
5338
5387
if (t.flags & TypeFlags.ContainsUndefinedOrNull) {
5339
5388
if (!reportWideningErrorsInType(t)) {
5340
5389
error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, p.name, typeToString(getWidenedType(t)));
5341
5390
}
5342
5391
errorReported = true;
5343
5392
}
5344
- });
5345
- return errorReported;
5393
+ }
5346
5394
}
5347
- return false ;
5395
+ return errorReported ;
5348
5396
}
5349
5397
5350
5398
function reportImplicitAnyError(declaration: Declaration, type: Type) {
@@ -5513,30 +5561,33 @@ namespace ts {
5513
5561
inferFromTypes(sourceType, target);
5514
5562
}
5515
5563
}
5516
- else if (source.flags & TypeFlags.ObjectType && (target.flags & (TypeFlags.Reference | TypeFlags.Tuple) ||
5517
- (target.flags & TypeFlags.Anonymous) && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class))) {
5518
- // If source is an object type, and target is a type reference, a tuple type, the type of a method, or a type literal, infer from members
5519
- if (isInProcess(source, target)) {
5520
- return;
5521
- }
5522
- if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) {
5523
- return;
5524
- }
5564
+ else {
5565
+ source = getApparentType(source);
5566
+ if (source.flags & TypeFlags.ObjectType && (target.flags & (TypeFlags.Reference | TypeFlags.Tuple) ||
5567
+ (target.flags & TypeFlags.Anonymous) && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class))) {
5568
+ // If source is an object type, and target is a type reference, a tuple type, the type of a method, or a type literal, infer from members
5569
+ if (isInProcess(source, target)) {
5570
+ return;
5571
+ }
5572
+ if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) {
5573
+ return;
5574
+ }
5525
5575
5526
- if (depth === 0) {
5527
- sourceStack = [];
5528
- targetStack = [];
5576
+ if (depth === 0) {
5577
+ sourceStack = [];
5578
+ targetStack = [];
5579
+ }
5580
+ sourceStack[depth] = source;
5581
+ targetStack[depth] = target;
5582
+ depth++;
5583
+ inferFromProperties(source, target);
5584
+ inferFromSignatures(source, target, SignatureKind.Call);
5585
+ inferFromSignatures(source, target, SignatureKind.Construct);
5586
+ inferFromIndexTypes(source, target, IndexKind.String, IndexKind.String);
5587
+ inferFromIndexTypes(source, target, IndexKind.Number, IndexKind.Number);
5588
+ inferFromIndexTypes(source, target, IndexKind.String, IndexKind.Number);
5589
+ depth--;
5529
5590
}
5530
- sourceStack[depth] = source;
5531
- targetStack[depth] = target;
5532
- depth++;
5533
- inferFromProperties(source, target);
5534
- inferFromSignatures(source, target, SignatureKind.Call);
5535
- inferFromSignatures(source, target, SignatureKind.Construct);
5536
- inferFromIndexTypes(source, target, IndexKind.String, IndexKind.String);
5537
- inferFromIndexTypes(source, target, IndexKind.Number, IndexKind.Number);
5538
- inferFromIndexTypes(source, target, IndexKind.String, IndexKind.Number);
5539
- depth--;
5540
5591
}
5541
5592
}
5542
5593
@@ -6949,7 +7000,6 @@ namespace ts {
6949
7000
}
6950
7001
}
6951
7002
6952
-
6953
7003
function checkJsxSelfClosingElement(node: JsxSelfClosingElement) {
6954
7004
checkJsxOpeningLikeElement(node);
6955
7005
return jsxElementType || anyType;
0 commit comments