Skip to content

Commit 13ca860

Browse files
author
Kanchalai Tanglertsampan
committed
Address comment: call getContextualType instead of accessing contextualType property directly
1 parent d3aaf30 commit 13ca860

4 files changed

Lines changed: 16 additions & 25 deletions

File tree

src/compiler/checker.ts

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7013,7 +7013,7 @@ namespace ts {
70137013
return true;
70147014
}
70157015
else if (getPropertyOfType(type, name) || (isComparingJsxAttributes && !isUnhyphenatedJsxName(name))) {
7016-
// For JSXAttributes, if the attribute has hyphenated name considered the attribute to be known
7016+
// For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known.
70177017
return true;
70187018
}
70197019
}
@@ -10527,27 +10527,19 @@ namespace ts {
1052710527

1052810528
function getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute) {
1052910529
// When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give JSXAttributes a contextual type
10530-
// which is a type of the parameter of the signature we are trying out. This is not the case if it is a statefull Jsx (i.e ReactComponenet class)
10530+
// which is a type of the parameter of the signature we are trying out. This is not the case if it is a stateful JSX (i.e ReactComponenet class)
1053110531
// So if that is the case, just return the type of the JsxAttribute in such contextual type with out going into resolving of the JsxOpeningLikeElement again
10532-
if ((<JsxAttributes>attribute.parent).contextualType) {
10533-
return isJsxAttribute(attribute) ? getTypeOfPropertyOfType((<JsxAttributes>attribute.parent).contextualType, attribute.name.text) : undefined;
10534-
}
10535-
10536-
const kind = attribute.kind;
10537-
const jsxElement = attribute.parent.parent as JsxOpeningLikeElement;
10538-
const attrsType = getAttributesTypeFromJsxOpeningLikeElement(jsxElement);
10532+
const attributesType = getContextualType(<Expression>attribute.parent) || getAttributesTypeFromJsxOpeningLikeElement(<JsxOpeningLikeElement>attribute.parent.parent);
1053910533

10540-
if (kind === SyntaxKind.JsxAttribute) {
10541-
if (!attrsType || isTypeAny(attrsType)) {
10534+
if (isJsxAttribute(attribute)) {
10535+
if (!attributesType || isTypeAny(attributesType)) {
1054210536
return undefined;
1054310537
}
10544-
return getTypeOfPropertyOfType(attrsType, (attribute as JsxAttribute).name.text);
10538+
return getTypeOfPropertyOfType(attributesType, (attribute as JsxAttribute).name.text);
1054510539
}
10546-
else if (kind === SyntaxKind.JsxSpreadAttribute) {
10547-
return attrsType;
10540+
else {
10541+
return attributesType;
1054810542
}
10549-
10550-
Debug.fail(`Expected JsxAttribute or JsxSpreadAttribute, got ts.SyntaxKind[${kind}]`);
1055110543
}
1055210544

1055310545
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
@@ -11228,7 +11220,7 @@ namespace ts {
1122811220
let sourceAttributesType = anyType as Type;
1122911221
let isSourceAttributesTypeEmpty = true;
1123011222
if (symbolArray) {
11231-
// Filter out any hyphenated names as those are not play any role in type-checking unless there are corresponding properties in the target type
11223+
// Filter out any hyphenated names as those do not play any role in type-checking unless there are corresponding properties in the target type
1123211224
const symbolTable = createMap<Symbol>();
1123311225
forEach(symbolArray, (attr) => {
1123411226
if (isUnhyphenatedJsxName(attr.name) || getPropertyOfType(targetAttributesType, attr.name)) {

src/compiler/types.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,14 +1427,13 @@ namespace ts {
14271427
attributes: JsxAttributes;
14281428
}
14291429

1430-
// @kind(SyntaxKind.JsxAttribute)
14311430
export interface JsxAttribute extends ObjectLiteralElement {
1431+
kind: SyntaxKind.JsxAttribute;
14321432
name: Identifier;
14331433
/// JSX attribute initializers are optional; <X y /> is sugar for <X y={true} />
14341434
initializer?: StringLiteral | JsxExpression;
14351435
}
14361436

1437-
// @kind(SyntaxKind.JsxSpreadAttribute)
14381437
export interface JsxSpreadAttribute extends ObjectLiteralElement {
14391438
kind: SyntaxKind.JsxSpreadAttribute;
14401439
expression: Expression;

tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(28,24): error TS2322: Type '{ extra: true; onClick: (k: any) => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'.
1+
tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(28,24): error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'.
22
Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'.
33
tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(29,24): error TS2322: Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'.
44
Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'.
55
tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(30,24): error TS2322: Type '{ extra: true; goTo: "home"; }' is not assignable to type 'IntrinsicAttributes & LinkProps'.
66
Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'.
77
tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(31,24): error TS2322: Type '{ goTo: "home"; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'.
88
Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'.
9-
tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(34,25): error TS2322: Type '{ extra: true; onClick: (k: any) => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'.
9+
tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(34,25): error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'.
1010
Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'.
1111
tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(37,25): error TS2322: Type '{ extra: true; goTo: "home"; }' is not assignable to type 'IntrinsicAttributes & LinkProps'.
1212
Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'.
@@ -42,7 +42,7 @@ tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(37,25): err
4242

4343
const b0 = <MainButton {...{onClick: (k) => {console.log(k)}}} extra />; // k has type any
4444
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45-
!!! error TS2322: Type '{ extra: true; onClick: (k: any) => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'.
45+
!!! error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'.
4646
!!! error TS2322: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'.
4747
const b2 = <MainButton onClick={(k)=>{console.log(k)}} extra />; // k has type "left" | "right"
4848
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -60,7 +60,7 @@ tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(37,25): err
6060
export function NoOverload(buttonProps: ButtonProps): JSX.Element { return undefined }
6161
const c1 = <NoOverload {...{onClick: (k) => {console.log(k)}}} extra />; // k has type any
6262
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
63-
!!! error TS2322: Type '{ extra: true; onClick: (k: any) => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'.
63+
!!! error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'.
6464
!!! error TS2322: Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'.
6565

6666
export function NoOverload1(linkProps: LinkProps): JSX.Element { return undefined }

tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ tests/cases/conformance/jsx/file.tsx(50,24): error TS2322: Type '{ to: string; o
44
Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'.
55
tests/cases/conformance/jsx/file.tsx(51,24): error TS2322: Type '{ onClick: () => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'.
66
Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'.
7-
tests/cases/conformance/jsx/file.tsx(52,24): error TS2322: Type '{ onClick: (k: any) => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'.
7+
tests/cases/conformance/jsx/file.tsx(52,24): error TS2322: Type '{ onClick: (k: MouseEvent<any>) => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'.
88
Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'.
99
tests/cases/conformance/jsx/file.tsx(54,24): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & HyphenProps'.
1010
Type '{}' is not assignable to type 'HyphenProps'.
@@ -84,7 +84,7 @@ tests/cases/conformance/jsx/file.tsx(57,24): error TS2322: Type '{ data-format:
8484
!!! error TS2322: Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'.
8585
const b3 = <MainButton {...{to: "10000"}} {...{onClick: (k) => {}}} />; // extra property
8686
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
87-
!!! error TS2322: Type '{ onClick: (k: any) => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'.
87+
!!! error TS2322: Type '{ onClick: (k: MouseEvent<any>) => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'.
8888
!!! error TS2322: Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'.
8989
const b4 = <MainButton {...obj3} to />; // Shoudld erro because Incorrect type; but attributes are any so everything is allowed
9090
const b5 = <MainButton {...{ onclick(){} }} />; // Spread doesn't retain method declaration

0 commit comments

Comments
 (0)