@@ -8884,6 +8884,10 @@ namespace ts {
8884
8884
return false;
8885
8885
}
8886
8886
8887
+ function isIgnoredJsxProperty(source: Type, sourceProp: Symbol, targetMemberType: Type | undefined) {
8888
+ return source.flags & TypeFlags.JsxAttributes && !(isUnhyphenatedJsxName(sourceProp.escapedName) || !!targetMemberType);
8889
+ }
8890
+
8887
8891
/**
8888
8892
* Checks if 'source' is related to 'target' (e.g.: is a assignable to).
8889
8893
* @param source The left-hand-side of the relation.
@@ -9580,10 +9584,6 @@ namespace ts {
9580
9584
return Ternary.False;
9581
9585
}
9582
9586
9583
- function isIgnoredJsxProperty(source: Type, sourceProp: Symbol, targetMemberType: Type | undefined) {
9584
- return source.flags & TypeFlags.JsxAttributes && !(isUnhyphenatedJsxName(sourceProp.escapedName) || !!targetMemberType);
9585
- }
9586
-
9587
9587
function propertiesRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary {
9588
9588
if (relation === identityRelation) {
9589
9589
return propertiesIdenticalTo(source, target);
@@ -14200,7 +14200,7 @@ namespace ts {
14200
14200
if (hasSpreadAnyType) {
14201
14201
return anyType;
14202
14202
}
14203
- return typeToIntersect ? getIntersectionType([typeToIntersect, ... spread === emptyObjectType ? [] : [ spread]] ) : spread;
14203
+ return typeToIntersect && spread !== emptyObjectType ? getIntersectionType([typeToIntersect, spread]) : (typeToIntersect || spread) ;
14204
14204
14205
14205
/**
14206
14206
* Create anonymous type from given attributes symbol table.
@@ -14810,11 +14810,16 @@ namespace ts {
14810
14810
// Check if sourceAttributesType assignable to targetAttributesType though this check will allow excess properties
14811
14811
const isSourceAttributeTypeAssignableToTarget = checkTypeAssignableTo(sourceAttributesType, targetAttributesType, openingLikeElement.attributes.properties.length > 0 ? openingLikeElement.attributes : openingLikeElement);
14812
14812
// After we check for assignability, we will do another pass to check that all explicitly specified attributes have correct name corresponding in targetAttributeType.
14813
- // This will allow excess properties in spread type as it is very common pattern to spread outter attributes into React component in its render method.
14813
+ // This will allow excess properties in spread type as it is very common pattern to spread outer attributes into React component in its render method.
14814
14814
if (isSourceAttributeTypeAssignableToTarget && !isTypeAny(sourceAttributesType) && !isTypeAny(targetAttributesType)) {
14815
14815
for (const attribute of openingLikeElement.attributes.properties) {
14816
- if (isJsxAttribute(attribute) && (isUnhyphenatedJsxName(idText(attribute.name)) || !!(getPropertyOfType(targetAttributesType, attribute.name.escapedText))) && !isKnownProperty(targetAttributesType, attribute.name.escapedText, /*isComparingJsxAttributes*/ true)) {
14817
- error(attribute, Diagnostics.Property_0_does_not_exist_on_type_1, idText(attribute.name), typeToString(targetAttributesType));
14816
+ if (isJsxAttribute(attribute)) {
14817
+ continue;
14818
+ }
14819
+ const attrName = attribute.name as Identifier;
14820
+ const isNotIgnoredJsxProperty = (isUnhyphenatedJsxName(idText(attrName)) || !!(getPropertyOfType(targetAttributesType, attrName.escapedText)));
14821
+ if (isNotIgnoredJsxProperty && !isKnownProperty(targetAttributesType, attrName.escapedText, /*isComparingJsxAttributes*/ true)) {
14822
+ error(attribute, Diagnostics.Property_0_does_not_exist_on_type_1, idText(attrName), typeToString(targetAttributesType));
14818
14823
// We break here so that errors won't be cascading
14819
14824
break;
14820
14825
}
@@ -15720,7 +15725,7 @@ namespace ts {
15720
15725
// However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props,
15721
15726
// can be specified by users through attributes property.
15722
15727
const paramType = getTypeAtPosition(signature, 0);
15723
- const attributesType = checkExpressionWithContextualType(node.attributes, paramType, /* contextualMapper */ undefined);
15728
+ const attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*contextualMapper*/ undefined);
15724
15729
const argProperties = getPropertiesOfType(attributesType);
15725
15730
for (const arg of argProperties) {
15726
15731
if (!getPropertyOfType(paramType, arg.escapedName) && isUnhyphenatedJsxName(arg.escapedName)) {
0 commit comments