@@ -1966,15 +1966,12 @@ namespace ts {
1966
1966
}
1967
1967
1968
1968
return _displayBuilder || (_displayBuilder = {
1969
- symbolToString: symbolToString,
1970
- typeToString: typeToString,
1971
1969
buildSymbolDisplay: buildSymbolDisplay,
1972
1970
buildTypeDisplay: buildTypeDisplay,
1973
1971
buildTypeParameterDisplay: buildTypeParameterDisplay,
1974
1972
buildParameterDisplay: buildParameterDisplay,
1975
1973
buildDisplayForParametersAndDelimiters: buildDisplayForParametersAndDelimiters,
1976
1974
buildDisplayForTypeParametersAndDelimiters: buildDisplayForTypeParametersAndDelimiters,
1977
- buildDisplayForTypeArgumentsAndDelimiters: buildDisplayForTypeArgumentsAndDelimiters,
1978
1975
buildTypeParameterDisplayFromSymbol: buildTypeParameterDisplayFromSymbol,
1979
1976
buildSignatureDisplay: buildSignatureDisplay,
1980
1977
buildReturnTypeDisplay: buildReturnTypeDisplay
@@ -4480,6 +4477,16 @@ namespace ts {
4480
4477
errorInfo = chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2);
4481
4478
}
4482
4479
4480
+ function reportRelationError(message: DiagnosticMessage, source: Type, target: Type) {
4481
+ let sourceType = typeToString(source);
4482
+ let targetType = typeToString(target);
4483
+ if (sourceType === targetType) {
4484
+ sourceType = typeToString(source, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType);
4485
+ targetType = typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType);
4486
+ }
4487
+ reportError(message || Diagnostics.Type_0_is_not_assignable_to_type_1, sourceType, targetType);
4488
+ }
4489
+
4483
4490
// Compare two types and return
4484
4491
// Ternary.True if they are related with no assumptions,
4485
4492
// Ternary.Maybe if they are related with assumptions of other relationships, or
@@ -4499,7 +4506,19 @@ namespace ts {
4499
4506
if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True;
4500
4507
}
4501
4508
}
4509
+
4510
+ if (relation === assignableRelation && source.flags & TypeFlags.ObjectLiteral && source.flags & TypeFlags.FreshObjectLiteral) {
4511
+ if (hasExcessProperties(<ObjectType>source, target, reportErrors)) {
4512
+ if (reportErrors) {
4513
+ reportRelationError(headMessage, source, target);
4514
+ }
4515
+ return Ternary.False;
4516
+ }
4517
+ source = getRegularTypeOfObjectLiteral(source);
4518
+ }
4519
+
4502
4520
let saveErrorInfo = errorInfo;
4521
+
4503
4522
if (source.flags & TypeFlags.Reference && target.flags & TypeFlags.Reference && (<TypeReference>source).target === (<TypeReference>target).target) {
4504
4523
// We have type references to same target type, see if relationship holds for all type arguments
4505
4524
if (result = typesRelatedTo((<TypeReference>source).typeArguments, (<TypeReference>target).typeArguments, reportErrors)) {
@@ -4576,18 +4595,28 @@ namespace ts {
4576
4595
}
4577
4596
4578
4597
if (reportErrors) {
4579
- headMessage = headMessage || Diagnostics.Type_0_is_not_assignable_to_type_1;
4580
- let sourceType = typeToString(source);
4581
- let targetType = typeToString(target);
4582
- if (sourceType === targetType) {
4583
- sourceType = typeToString(source, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType);
4584
- targetType = typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType);
4585
- }
4586
- reportError(headMessage, sourceType, targetType);
4598
+ reportRelationError(headMessage, source, target);
4587
4599
}
4588
4600
return Ternary.False;
4589
4601
}
4590
4602
4603
+ function hasExcessProperties(source: ObjectType, target: Type, reportErrors: boolean): boolean {
4604
+ if (target.flags & TypeFlags.ObjectType) {
4605
+ var resolved = resolveStructuredTypeMembers(target);
4606
+ if (resolved.properties.length > 0 && !resolved.stringIndexType && !resolved.numberIndexType) {
4607
+ for (let prop of getPropertiesOfObjectType(source)) {
4608
+ if (!getPropertyOfType(target, prop.name)) {
4609
+ if (reportErrors) {
4610
+ reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(target));
4611
+ }
4612
+ return true;
4613
+ }
4614
+ }
4615
+ }
4616
+ }
4617
+ return false;
4618
+ }
4619
+
4591
4620
function eachTypeRelatedToSomeType(source: UnionOrIntersectionType, target: UnionOrIntersectionType): Ternary {
4592
4621
let result = Ternary.True;
4593
4622
let sourceTypes = source.types;
@@ -5255,6 +5284,24 @@ namespace ts {
5255
5284
return (type.flags & TypeFlags.Tuple) && !!(<TupleType>type).elementTypes;
5256
5285
}
5257
5286
5287
+ function getRegularTypeOfObjectLiteral(type: Type): Type {
5288
+ if (type.flags & TypeFlags.FreshObjectLiteral) {
5289
+ let regularType = (<FreshObjectLiteralType>type).regularType;
5290
+ if (!regularType) {
5291
+ regularType = <ResolvedType>createType((<ResolvedType>type).flags & ~TypeFlags.FreshObjectLiteral);
5292
+ regularType.symbol = (<ResolvedType>type).symbol;
5293
+ regularType.members = (<ResolvedType>type).members;
5294
+ regularType.properties = (<ResolvedType>type).properties;
5295
+ regularType.callSignatures = (<ResolvedType>type).callSignatures;
5296
+ regularType.constructSignatures = (<ResolvedType>type).constructSignatures;
5297
+ regularType.stringIndexType = (<ResolvedType>type).stringIndexType;
5298
+ regularType.numberIndexType = (<ResolvedType>type).numberIndexType;
5299
+ }
5300
+ return regularType;
5301
+ }
5302
+ return type;
5303
+ }
5304
+
5258
5305
function getWidenedTypeOfObjectLiteral(type: Type): Type {
5259
5306
let properties = getPropertiesOfObjectType(type);
5260
5307
let members: SymbolTable = {};
@@ -6830,18 +6877,6 @@ namespace ts {
6830
6877
return links.resolvedType;
6831
6878
}
6832
6879
6833
- function isPermittedProperty(contextualType: Type, propName: string): boolean {
6834
- if (contextualType.flags & TypeFlags.ObjectType) {
6835
- let resolved = resolveStructuredTypeMembers(<ObjectType>contextualType);
6836
- return !!(resolved.properties.length === 0 || resolved.stringIndexType ||
6837
- resolved.numberIndexType || getPropertyOfObjectType(contextualType, propName));
6838
- }
6839
- if (contextualType.flags & TypeFlags.UnionOrIntersection) {
6840
- return !forEach((<UnionOrIntersectionType>contextualType).types, type => !isPermittedProperty(type, propName));
6841
- }
6842
- return true;
6843
- }
6844
-
6845
6880
function checkObjectLiteral(node: ObjectLiteralExpression, contextualMapper?: TypeMapper): Type {
6846
6881
// Grammar checking
6847
6882
checkGrammarObjectLiteralExpression(node);
@@ -6891,17 +6926,14 @@ namespace ts {
6891
6926
6892
6927
if (!hasDynamicName(memberDecl)) {
6893
6928
propertiesTable[member.name] = member;
6894
- if (contextualType && !isPermittedProperty(contextualType, member.name)) {
6895
- error(memberDecl.name, Diagnostics.Property_0_does_not_exist_in_contextual_type_1, member.name, typeToString(contextualType));
6896
- }
6897
6929
}
6898
6930
propertiesArray.push(member);
6899
6931
}
6900
6932
6901
6933
let stringIndexType = getIndexType(IndexKind.String);
6902
6934
let numberIndexType = getIndexType(IndexKind.Number);
6903
6935
let result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType);
6904
- result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsUndefinedOrNull);
6936
+ result.flags |= TypeFlags.ObjectLiteral | TypeFlags.FreshObjectLiteral | TypeFlags. ContainsObjectLiteral | (typeFlags & TypeFlags.ContainsUndefinedOrNull);
6905
6937
return result;
6906
6938
6907
6939
function getIndexType(kind: IndexKind) {
@@ -8782,7 +8814,7 @@ namespace ts {
8782
8814
}
8783
8815
8784
8816
function checkAssertion(node: AssertionExpression) {
8785
- let exprType = checkExpression(node.expression);
8817
+ let exprType = getRegularTypeOfObjectLiteral( checkExpression(node.expression) );
8786
8818
let targetType = getTypeFromTypeNode(node.type);
8787
8819
if (produceDiagnostics && targetType !== unknownType) {
8788
8820
let widenedType = getWidenedType(exprType);
@@ -9559,7 +9591,7 @@ namespace ts {
9559
9591
return getUnionType([leftType, rightType]);
9560
9592
case SyntaxKind.EqualsToken:
9561
9593
checkAssignmentOperator(rightType);
9562
- return rightType;
9594
+ return getRegularTypeOfObjectLiteral( rightType) ;
9563
9595
case SyntaxKind.CommaToken:
9564
9596
return rightType;
9565
9597
}
0 commit comments