Skip to content

Commit f583ec1

Browse files
author
Kanchalai Tanglertsampan
committed
wip-using overload resolution to figure out stateless functions
1 parent 8c9bdf2 commit f583ec1

File tree

7 files changed

+67
-35
lines changed

7 files changed

+67
-35
lines changed

src/compiler/checker.ts

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6834,7 +6834,8 @@ namespace ts {
68346834
function isKnownProperty(type: Type, name: string): boolean {
68356835
if (type.flags & TypeFlags.ObjectType) {
68366836
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)) ||
68386839
resolved.stringIndexInfo ||
68396840
(resolved.numberIndexInfo && isNumericLiteralName(name)) ||
68406841
getPropertyOfType(type, name)) {
@@ -10786,7 +10787,7 @@ namespace ts {
1078610787
result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag;
1078710788
return result;
1078810789
}
10789-
10790+
1079010791
/**
1079110792
* Check attributes type of intrinsic JSx opening-like element.
1079210793
* 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 {
1081410815
* Check the attributes of the given JsxOpeningLikeElement.
1081510816
* Resolve the type of attributes of the openingLikeElement
1081610817
* Compare if the given attributes assignable to attributes type resolved from the type of opening-element
10818+
* @param openingLikeElement
1081710819
*/
1081810820
function checkJsxAttributes(openingLikeElement: JsxOpeningLikeElement) {
10821+
let targetAttributesType: Type;
1081910822
// Get target attributes type from resolving opening-element
1082010823
// Check if given attributes (openingLikeELement.attributes) are compatible with the given attributes
1082110824
if (isJsxIntrinsicIdentifier(openingLikeElement.tagName)) {
10822-
checkAttributesTypeOfIntrinsicJsxOpeningLikeElement(openingLikeElement);
10825+
targetAttributesType = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(openingLikeElement);
1082310826
}
1082410827
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;
1083610842
}
10837-
sourceAttributesType = createJsxAttributesType(openingLikeElement.attributes, attributesTable);
1083810843
}
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);
1084010852
}
1084110853
}
1084210854

@@ -12448,7 +12460,8 @@ namespace ts {
1244812460
resultOfFailedInference = undefined;
1244912461
result = chooseOverload(candidates, assignableRelation, signatureHelpTrailingComma);
1245012462
}
12451-
if (result) {
12463+
// TODO (yuisu): comment
12464+
if (result || isJsxOpeningLikeElement) {
1245212465
return result;
1245312466
}
1245412467

@@ -12462,8 +12475,7 @@ namespace ts {
1246212475
// in arguments too early. If possible, we'd like to only type them once we know the correct
1246312476
// overload. However, this matters for the case where the call is correct. When the call is
1246412477
// 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);
1246712479
}
1246812480
else if (candidateForTypeArgumentError) {
1246912481
if (!isTaggedTemplate && !isDecorator && typeArguments) {

tests/baselines/reference/tsxAttributeResolution10.errors.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
tests/cases/conformance/jsx/file.tsx(11,14): error TS2322: Type '"world"' is not assignable to type 'boolean'.
1+
tests/cases/conformance/jsx/file.tsx(11,14): error TS2322: Type '{ bar: "world"; }' is not assignable to type '{ [s: string]: boolean; }'.
2+
Property 'bar' is incompatible with index signature.
3+
Type '"world"' is not assignable to type 'boolean'.
24

35

46
==== tests/cases/conformance/jsx/react.d.ts (0 errors) ====
@@ -25,7 +27,9 @@ tests/cases/conformance/jsx/file.tsx(11,14): error TS2322: Type '"world"' is not
2527
// Should be an error
2628
<MyComponent bar='world' />;
2729
~~~~~~~~~~~
28-
!!! error TS2322: Type '"world"' is not assignable to type 'boolean'.
30+
!!! error TS2322: Type '{ bar: "world"; }' is not assignable to type '{ [s: string]: boolean; }'.
31+
!!! error TS2322: Property 'bar' is incompatible with index signature.
32+
!!! error TS2322: Type '"world"' is not assignable to type 'boolean'.
2933

3034
// Should be OK
3135
<MyComponent bar={true} />;

tests/baselines/reference/tsxAttributeResolution11.errors.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
tests/cases/conformance/jsx/file.tsx(11,22): error TS2339: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'.
1+
tests/cases/conformance/jsx/file.tsx(11,22): error TS2322: Type '{ bar: "world"; }' is not assignable to type 'IntrinsicAttributes & { ref?: string; }'.
2+
Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'.
23

34

45
==== tests/cases/conformance/jsx/react.d.ts (0 errors) ====
@@ -27,7 +28,8 @@ tests/cases/conformance/jsx/file.tsx(11,22): error TS2339: Property 'bar' does n
2728

2829
// Should be an OK
2930
var x = <MyComponent bar='world' />;
30-
~~~
31-
!!! error TS2339: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'.
31+
~~~~~~~~~~~
32+
!!! error TS2322: Type '{ bar: "world"; }' is not assignable to type 'IntrinsicAttributes & { ref?: string; }'.
33+
!!! error TS2322: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'.
3234

3335

tests/baselines/reference/tsxAttributeResolution12.errors.txt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
tests/cases/conformance/jsx/file.tsx(26,10): error TS2324: Property 'reqd' is missing in type 'IntrinsicAttributes & { reqd: any; }'.
2-
tests/cases/conformance/jsx/file.tsx(29,10): error TS2324: Property 'reqd' is missing in type 'IntrinsicAttributes & { reqd: any; }'.
1+
tests/cases/conformance/jsx/file.tsx(26,10): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { reqd: any; }'.
2+
Type '{}' is not assignable to type '{ reqd: any; }'.
3+
Property 'reqd' is missing in type '{}'.
4+
tests/cases/conformance/jsx/file.tsx(29,10): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { reqd: any; }'.
5+
Type '{}' is not assignable to type '{ reqd: any; }'.
6+
Property 'reqd' is missing in type '{}'.
37

48

59
==== tests/cases/conformance/jsx/react.d.ts (0 errors) ====
@@ -44,11 +48,15 @@ tests/cases/conformance/jsx/file.tsx(29,10): error TS2324: Property 'reqd' is mi
4448
const T = TestMod.Test;
4549
var t1 = <T />;
4650
~~~~~
47-
!!! error TS2324: Property 'reqd' is missing in type 'IntrinsicAttributes & { reqd: any; }'.
51+
!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { reqd: any; }'.
52+
!!! error TS2322: Type '{}' is not assignable to type '{ reqd: any; }'.
53+
!!! error TS2322: Property 'reqd' is missing in type '{}'.
4854

4955
// Should error
5056
var t2 = <TestMod.Test />;
5157
~~~~~~~~~~~~~~~~
52-
!!! error TS2324: Property 'reqd' is missing in type 'IntrinsicAttributes & { reqd: any; }'.
58+
!!! error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & { reqd: any; }'.
59+
!!! error TS2322: Type '{}' is not assignable to type '{ reqd: any; }'.
60+
!!! error TS2322: Property 'reqd' is missing in type '{}'.
5361

5462

tests/baselines/reference/tsxAttributeResolution9.errors.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
tests/cases/conformance/jsx/file.tsx(9,14): error TS2322: Type '0' is not assignable to type 'string'.
1+
tests/cases/conformance/jsx/file.tsx(9,14): error TS2322: Type '{ foo: 0; }' is not assignable to type '{ foo: string; }'.
2+
Types of property 'foo' are incompatible.
3+
Type '0' is not assignable to type 'string'.
24

35

46
==== tests/cases/conformance/jsx/react.d.ts (0 errors) ====
@@ -27,5 +29,7 @@ tests/cases/conformance/jsx/file.tsx(9,14): error TS2322: Type '0' is not assign
2729
<MyComponent foo="bar" />; // ok
2830
<MyComponent foo={0} />; // should be an error
2931
~~~~~~~
30-
!!! error TS2322: Type '0' is not assignable to type 'string'.
32+
!!! error TS2322: Type '{ foo: 0; }' is not assignable to type '{ foo: string; }'.
33+
!!! error TS2322: Types of property 'foo' are incompatible.
34+
!!! error TS2322: Type '0' is not assignable to type 'string'.
3135

tests/baselines/reference/tsxElementResolution11.errors.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
tests/cases/conformance/jsx/file.tsx(17,7): error TS2339: Property 'x' does not exist on type '{ q?: number; }'.
1+
tests/cases/conformance/jsx/file.tsx(17,7): error TS2322: Type '{ x: 10; }' is not assignable to type '{ q?: number; }'.
2+
Property 'x' does not exist on type '{ q?: number; }'.
23

34

45
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
@@ -19,8 +20,9 @@ tests/cases/conformance/jsx/file.tsx(17,7): error TS2339: Property 'x' does not
1920
}
2021
var Obj2: Obj2type;
2122
<Obj2 x={10} />; // Error
22-
~
23-
!!! error TS2339: Property 'x' does not exist on type '{ q?: number; }'.
23+
~~~~~~
24+
!!! error TS2322: Type '{ x: 10; }' is not assignable to type '{ q?: number; }'.
25+
!!! error TS2322: Property 'x' does not exist on type '{ q?: number; }'.
2426

2527
interface Obj3type {
2628
new(n: string): { x: number; };

tests/cases/conformance/jsx/tsxElementResolution12.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ var Obj1: Obj1type;
1515
interface Obj2type {
1616
new(n: string): { q?: number; pr: any };
1717
}
18-
var obj2: Obj2type;
19-
<Obj2 x={10} />; // OK
18+
var Obj2: Obj2type;
19+
<Obj2 x={10} />; // Error
2020

2121
interface Obj3type {
2222
new(n: string): { x: number; };

0 commit comments

Comments
 (0)