@@ -6834,7 +6834,8 @@ namespace ts {
6834
6834
function isKnownProperty(type: Type, name: string): boolean {
6835
6835
if (type.flags & TypeFlags.ObjectType) {
6836
6836
const resolved = resolveStructuredTypeMembers(type);
6837
- if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyObjectType(resolved)) ||
6837
+ if ((relation === assignableRelation || relation === comparableRelation) &&
6838
+ (type === globalObjectType || isEmptyObjectType(resolved)) ||
6838
6839
resolved.stringIndexInfo ||
6839
6840
(resolved.numberIndexInfo && isNumericLiteralName(name)) ||
6840
6841
getPropertyOfType(type, name)) {
@@ -10786,7 +10787,7 @@ namespace ts {
10786
10787
result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag;
10787
10788
return result;
10788
10789
}
10789
-
10790
+
10790
10791
/**
10791
10792
* Check attributes type of intrinsic JSx opening-like element.
10792
10793
* The function is intended to be called from checkJsxAttributes which has already check the the opening-like element is an intrinsic element.
@@ -10814,29 +10815,40 @@ namespace ts {
10814
10815
* Check the attributes of the given JsxOpeningLikeElement.
10815
10816
* Resolve the type of attributes of the openingLikeElement
10816
10817
* Compare if the given attributes assignable to attributes type resolved from the type of opening-element
10818
+ * @param openingLikeElement
10817
10819
*/
10818
10820
function checkJsxAttributes(openingLikeElement: JsxOpeningLikeElement) {
10821
+ let targetAttributesType: Type;
10819
10822
// Get target attributes type from resolving opening-element
10820
10823
// Check if given attributes (openingLikeELement.attributes) are compatible with the given attributes
10821
10824
if (isJsxIntrinsicIdentifier(openingLikeElement.tagName)) {
10822
- checkAttributesTypeOfIntrinsicJsxOpeningLikeElement (openingLikeElement);
10825
+ targetAttributesType = getIntrinsicAttributesTypeFromJsxOpeningLikeElement (openingLikeElement);
10823
10826
}
10824
10827
else {
10825
- const targetAttributesType = getCustomJsxElementAttributesType(openingLikeElement);
10826
- const symbolTable = getAttributesSymbolTableOfJsxOpeningLikeElement(openingLikeElement);
10827
- // Filter out any hyphenated names as those are not play any role in type-checking unless there are corresponding properties in the target type
10828
- let attributesTable: Map<Symbol>;
10829
- let sourceAttributesType = anyType as Type;
10830
- if (symbolTable) {
10831
- attributesTable = createMap<Symbol>();
10832
- for (const key in symbolTable) {
10833
- if (isUnhyphenatedJsxName(key) || getPropertyOfType(targetAttributesType, key)) {
10834
- attributesTable[key] = symbolTable[key];
10835
- }
10828
+ targetAttributesType = getCustomJsxElementAttributesType(openingLikeElement);
10829
+ }
10830
+
10831
+ const symbolTable = getAttributesSymbolTableOfJsxOpeningLikeElement(openingLikeElement);
10832
+ // Filter out any hyphenated names as those are not play any role in type-checking unless there are corresponding properties in the target type
10833
+ let attributesTable: Map<Symbol>;
10834
+ let sourceAttributesType = anyType as Type;
10835
+ let isSourceAttributesTypeEmpty = true;
10836
+ if (symbolTable) {
10837
+ attributesTable = createMap<Symbol>();
10838
+ for (const key in symbolTable) {
10839
+ if (isUnhyphenatedJsxName(key) || getPropertyOfType(targetAttributesType, key)) {
10840
+ attributesTable[key] = symbolTable[key];
10841
+ isSourceAttributesTypeEmpty = false;
10836
10842
}
10837
- sourceAttributesType = createJsxAttributesType(openingLikeElement.attributes, attributesTable);
10838
10843
}
10839
- checkTypeAssignableTo(sourceAttributesType, targetAttributesType, openingLikeElement.attributes.properties.length > 0 ? openingLikeElement.attributes : openingLikeElement);
10844
+ sourceAttributesType = createJsxAttributesType(openingLikeElement.attributes, attributesTable);
10845
+ }
10846
+ // TODO(yuisu): comment
10847
+ if (targetAttributesType === emptyObjectType && !isTypeAny(sourceAttributesType) && !isSourceAttributesTypeEmpty) {
10848
+ error(openingLikeElement, Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, getJsxElementPropertiesName());
10849
+ }
10850
+ else {
10851
+ checkTypeAssignableTo(sourceAttributesType, targetAttributesType, openingLikeElement.attributes.properties.length > 0 ? openingLikeElement.attributes : openingLikeElement);
10840
10852
}
10841
10853
}
10842
10854
@@ -12448,7 +12460,8 @@ namespace ts {
12448
12460
resultOfFailedInference = undefined;
12449
12461
result = chooseOverload(candidates, assignableRelation, signatureHelpTrailingComma);
12450
12462
}
12451
- if (result) {
12463
+ // TODO (yuisu): comment
12464
+ if (result || isJsxOpeningLikeElement) {
12452
12465
return result;
12453
12466
}
12454
12467
@@ -12462,8 +12475,7 @@ namespace ts {
12462
12475
// in arguments too early. If possible, we'd like to only type them once we know the correct
12463
12476
// overload. However, this matters for the case where the call is correct. When the call is
12464
12477
// an error, we don't need to exclude any arguments, although it would cause no harm to do so.
12465
- // TODO (yuisu): comment
12466
- checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ isJsxOpeningLikeElement ? false: true);
12478
+ checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ true);
12467
12479
}
12468
12480
else if (candidateForTypeArgumentError) {
12469
12481
if (!isTaggedTemplate && !isDecorator && typeArguments) {
0 commit comments