@@ -11836,7 +11836,7 @@ namespace ts {
11836
11836
if (!noImplicitAny && getObjectFlags(target) & ObjectFlags.JSLiteral) {
11837
11837
return false; // Disable excess property checks on JS literals to simulate having an implicit "index signature" - but only outside of noImplicitAny
11838
11838
}
11839
- if (maybeTypeOfKind (target, TypeFlags.Object) && !(getObjectFlags(target) & ObjectFlags.ObjectLiteralPatternWithComputedProperties )) {
11839
+ if (isExcessPropertyCheckTarget (target)) {
11840
11840
const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes);
11841
11841
if ((relation === assignableRelation || relation === definitelyAssignableRelation || relation === comparableRelation) &&
11842
11842
(isTypeSubsetOf(globalObjectType, target) || (!isComparingJsxAttributes && isEmptyObjectType(target)))) {
@@ -11849,6 +11849,9 @@ namespace ts {
11849
11849
for (const prop of getPropertiesOfObjectType(source)) {
11850
11850
if (shouldCheckAsExcessProperty(prop, source.symbol) && !isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) {
11851
11851
if (reportErrors) {
11852
+ // Report error in terms of object types in the target as those are the only ones
11853
+ // we check in isKnownProperty.
11854
+ const errorTarget = filterType(target, isExcessPropertyCheckTarget);
11852
11855
// We know *exactly* where things went wrong when comparing the types.
11853
11856
// Use this property as the error node as this will be more helpful in
11854
11857
// reasoning about what went wrong.
@@ -11857,7 +11860,7 @@ namespace ts {
11857
11860
// JsxAttributes has an object-literal flag and undergo same type-assignablity check as normal object-literal.
11858
11861
// However, using an object-literal error message will be very confusing to the users so we give different a message.
11859
11862
// TODO: Spelling suggestions for excess jsx attributes (needs new diagnostic messages)
11860
- reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(target ));
11863
+ reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(errorTarget ));
11861
11864
}
11862
11865
else {
11863
11866
// use the property's value declaration if the property is assigned inside the literal itself
@@ -11871,17 +11874,17 @@ namespace ts {
11871
11874
11872
11875
const name = propDeclaration.name!;
11873
11876
if (isIdentifier(name)) {
11874
- suggestion = getSuggestionForNonexistentProperty(name, target );
11877
+ suggestion = getSuggestionForNonexistentProperty(name, errorTarget );
11875
11878
}
11876
11879
}
11877
11880
11878
11881
if (suggestion !== undefined) {
11879
11882
reportError(Diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2,
11880
- symbolToString(prop), typeToString(target ), suggestion);
11883
+ symbolToString(prop), typeToString(errorTarget ), suggestion);
11881
11884
}
11882
11885
else {
11883
11886
reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1,
11884
- symbolToString(prop), typeToString(target ));
11887
+ symbolToString(prop), typeToString(errorTarget ));
11885
11888
}
11886
11889
}
11887
11890
}
@@ -18595,20 +18598,23 @@ namespace ts {
18595
18598
return true;
18596
18599
}
18597
18600
}
18598
- else if (targetType.flags & TypeFlags.UnionOrIntersection) {
18601
+ else if (targetType.flags & TypeFlags.UnionOrIntersection && isExcessPropertyCheckTarget(targetType) ) {
18599
18602
for (const t of (targetType as UnionOrIntersectionType).types) {
18600
18603
if (isKnownProperty(t, name, isComparingJsxAttributes)) {
18601
18604
return true;
18602
18605
}
18603
18606
}
18604
18607
}
18605
- else if (targetType.flags & TypeFlags.Conditional) {
18606
- return isKnownProperty((targetType as ConditionalType).root.trueType, name, isComparingJsxAttributes) ||
18607
- isKnownProperty((targetType as ConditionalType).root.falseType, name, isComparingJsxAttributes);
18608
- }
18609
18608
return false;
18610
18609
}
18611
18610
18611
+ function isExcessPropertyCheckTarget(type: Type): boolean {
18612
+ return !!(type.flags & TypeFlags.Object && !(getObjectFlags(type) & ObjectFlags.ObjectLiteralPatternWithComputedProperties) ||
18613
+ type.flags & TypeFlags.NonPrimitive ||
18614
+ type.flags & TypeFlags.Union && some((<UnionType>type).types, isExcessPropertyCheckTarget) ||
18615
+ type.flags & TypeFlags.Intersection && every((<IntersectionType>type).types, isExcessPropertyCheckTarget));
18616
+ }
18617
+
18612
18618
function checkJsxExpression(node: JsxExpression, checkMode?: CheckMode) {
18613
18619
if (node.expression) {
18614
18620
const type = checkExpression(node.expression, checkMode);
0 commit comments