Skip to content

Commit 350f47a

Browse files
author
Kanchalai Tanglertsampan
committed
Address comment: call getContextualType instead of accessing contextualType property directly
1 parent 2fd5667 commit 350f47a

File tree

4 files changed

+16
-25
lines changed

4 files changed

+16
-25
lines changed

src/compiler/checker.ts

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7600,7 +7600,7 @@ namespace ts {
76007600
return true;
76017601
}
76027602
else if (getPropertyOfType(type, name) || (isComparingJsxAttributes && !isUnhyphenatedJsxName(name))) {
7603-
// For JSXAttributes, if the attribute has hyphenated name considered the attribute to be known
7603+
// For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known.
76047604
return true;
76057605
}
76067606
}
@@ -11281,27 +11281,19 @@ namespace ts {
1128111281

1128211282
function getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute) {
1128311283
// When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give JSXAttributes a contextual type
11284-
// 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)
11284+
// 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)
1128511285
// 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
11286-
if ((<JsxAttributes>attribute.parent).contextualType) {
11287-
return isJsxAttribute(attribute) ? getTypeOfPropertyOfType((<JsxAttributes>attribute.parent).contextualType, attribute.name.text) : undefined;
11288-
}
11289-
11290-
const kind = attribute.kind;
11291-
const jsxElement = attribute.parent.parent as JsxOpeningLikeElement;
11292-
const attrsType = getAttributesTypeFromJsxOpeningLikeElement(jsxElement);
11286+
const attributesType = getContextualType(<Expression>attribute.parent) || getAttributesTypeFromJsxOpeningLikeElement(<JsxOpeningLikeElement>attribute.parent.parent);
1129311287

11294-
if (kind === SyntaxKind.JsxAttribute) {
11295-
if (!attrsType || isTypeAny(attrsType)) {
11288+
if (isJsxAttribute(attribute)) {
11289+
if (!attributesType || isTypeAny(attributesType)) {
1129611290
return undefined;
1129711291
}
11298-
return getTypeOfPropertyOfType(attrsType, (attribute as JsxAttribute).name.text);
11292+
return getTypeOfPropertyOfType(attributesType, (attribute as JsxAttribute).name.text);
1129911293
}
11300-
else if (kind === SyntaxKind.JsxSpreadAttribute) {
11301-
return attrsType;
11294+
else {
11295+
return attributesType;
1130211296
}
11303-
11304-
Debug.fail(`Expected JsxAttribute or JsxSpreadAttribute, got ts.SyntaxKind[${kind}]`);
1130511297
}
1130611298

1130711299
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
@@ -11992,7 +11984,7 @@ namespace ts {
1199211984
let sourceAttributesType = anyType as Type;
1199311985
let isSourceAttributesTypeEmpty = true;
1199411986
if (symbolArray) {
11995-
// Filter out any hyphenated names as those are not play any role in type-checking unless there are corresponding properties in the target type
11987+
// Filter out any hyphenated names as those do not play any role in type-checking unless there are corresponding properties in the target type
1199611988
const symbolTable = createMap<Symbol>();
1199711989
forEach(symbolArray, (attr) => {
1199811990
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
@@ -1507,14 +1507,13 @@
15071507
attributes: JsxAttributes;
15081508
}
15091509

1510-
// @kind(SyntaxKind.JsxAttribute)
15111510
export interface JsxAttribute extends ObjectLiteralElement {
1511+
kind: SyntaxKind.JsxAttribute;
15121512
name: Identifier;
15131513
/// JSX attribute initializers are optional; <X y /> is sugar for <X y={true} />
15141514
initializer?: StringLiteral | JsxExpression;
15151515
}
15161516

1517-
// @kind(SyntaxKind.JsxSpreadAttribute)
15181517
export interface JsxSpreadAttribute extends ObjectLiteralElement {
15191518
kind: SyntaxKind.JsxSpreadAttribute;
15201519
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 '{ to: string; onClick(e: any): void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'.
1010
Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'.
@@ -81,7 +81,7 @@ tests/cases/conformance/jsx/file.tsx(57,24): error TS2322: Type '{ data-format:
8181
!!! error TS2322: Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'.
8282
const b3 = <MainButton {...{to: "10000"}} {...{onClick: (k) => {}}} />; // extra property
8383
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
84-
!!! error TS2322: Type '{ onClick: (k: any) => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'.
84+
!!! error TS2322: Type '{ onClick: (k: MouseEvent<any>) => void; to: string; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'.
8585
!!! error TS2322: Property 'onClick' does not exist on type 'IntrinsicAttributes & HyphenProps'.
8686
const b4 = <MainButton {...obj3} to />; // Should error because Incorrect type; but attributes are any so everything is allowed
8787
const b5 = <MainButton {...{ onClick(e: any) { } }} {...obj0} />; // Spread retain method declaration (see GitHub #13365), so now there is an extra attributes

0 commit comments

Comments
 (0)