From 64c96323aaedbecf32953144942b3ef8ed2db37c Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 23 Dec 2015 16:38:07 -0800 Subject: [PATCH 1/4] Added test. --- ...uallyTypedStringLiteralsInJsxAttributes01.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx diff --git a/tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx b/tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx new file mode 100644 index 00000000000..ce6f4b7ac2f --- /dev/null +++ b/tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx @@ -0,0 +1,16 @@ +// @jsx: preserve +// @declaration: true + +namespace JSX { + interface IntrinsicElements { + span: {}; + } +} + +const FooComponent = (props: { foo: "A" | "B" | "C" }) => {props.foo}; + +; +; + +; +; \ No newline at end of file From 4dc85dcbd68f559a433a5b917c183569066e133d Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 23 Dec 2015 16:53:02 -0800 Subject: [PATCH 2/4] Accepted baselines. --- ...StringLiteralsInJsxAttributes01.errors.txt | 32 +++++++++++++++++++ ...llyTypedStringLiteralsInJsxAttributes01.js | 30 +++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.errors.txt create mode 100644 tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.js diff --git a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.errors.txt b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.errors.txt new file mode 100644 index 00000000000..99bb5d6daf5 --- /dev/null +++ b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.errors.txt @@ -0,0 +1,32 @@ +tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx(11,15): error TS2322: Type 'string' is not assignable to type '"A" | "B" | "C"'. + Type 'string' is not assignable to type '"C"'. +tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx(13,15): error TS2322: Type '"f"' is not assignable to type '"A" | "B" | "C"'. + Type '"f"' is not assignable to type '"C"'. +tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx(14,15): error TS2322: Type 'string' is not assignable to type '"A" | "B" | "C"'. + Type 'string' is not assignable to type '"C"'. + + +==== tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx (3 errors) ==== + + namespace JSX { + interface IntrinsicElements { + span: {}; + } + } + + const FooComponent = (props: { foo: "A" | "B" | "C" }) => {props.foo}; + + ; + ; + ~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type '"A" | "B" | "C"'. +!!! error TS2322: Type 'string' is not assignable to type '"C"'. + + ; + ~~~~~~~~~ +!!! error TS2322: Type '"f"' is not assignable to type '"A" | "B" | "C"'. +!!! error TS2322: Type '"f"' is not assignable to type '"C"'. + ; + ~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type '"A" | "B" | "C"'. +!!! error TS2322: Type 'string' is not assignable to type '"C"'. \ No newline at end of file diff --git a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.js b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.js new file mode 100644 index 00000000000..c21247c2835 --- /dev/null +++ b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.js @@ -0,0 +1,30 @@ +//// [contextuallyTypedStringLiteralsInJsxAttributes01.tsx] + +namespace JSX { + interface IntrinsicElements { + span: {}; + } +} + +const FooComponent = (props: { foo: "A" | "B" | "C" }) => {props.foo}; + +; +; + +; +; + +//// [contextuallyTypedStringLiteralsInJsxAttributes01.jsx] +var FooComponent = function (props) { return {props.foo}; }; +; +; +; +; + + +//// [contextuallyTypedStringLiteralsInJsxAttributes01.d.ts] +declare namespace JSX { +} +declare const FooComponent: (props: { + foo: "A" | "B" | "C"; +}) => any; From a0ef319f5db91c36b7b9a6ad161ec713f754d3fc Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 23 Dec 2015 17:10:16 -0800 Subject: [PATCH 3/4] Simplified JSX contextual typing code and added support for contextually typing string literal attribute initializers. --- src/compiler/checker.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5d57e9d2028..00bddd2f7b1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7464,24 +7464,22 @@ namespace ts { return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional) : undefined; } - function getContextualTypeForJsxExpression(expr: JsxExpression | JsxSpreadAttribute): Type { - // Contextual type only applies to JSX expressions that are in attribute assignments (not in 'Children' positions) - if (expr.parent.kind === SyntaxKind.JsxAttribute) { - const attrib = expr.parent; - const attrsType = getJsxElementAttributesType(attrib.parent); + function getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute) { + const kind = attribute.kind; + const jsxElement = attribute.parent as JsxOpeningLikeElement; + const attrsType = getJsxElementAttributesType(jsxElement); + + if (attribute.kind === SyntaxKind.JsxAttribute) { if (!attrsType || isTypeAny(attrsType)) { return undefined; } - else { - return getTypeOfPropertyOfType(attrsType, attrib.name.text); - } + return getTypeOfPropertyOfType(attrsType, (attribute as JsxAttribute).name.text); + } + else if (attribute.kind === SyntaxKind.JsxSpreadAttribute) { + return attrsType; } - if (expr.kind === SyntaxKind.JsxSpreadAttribute) { - return getJsxElementAttributesType(expr.parent); - } - - return undefined; + Debug.fail(`Expected JsxAttribute or JsxSpreadAttribute, got ts.SyntaxKind[${kind}]`); } // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily @@ -7549,8 +7547,10 @@ namespace ts { case SyntaxKind.ParenthesizedExpression: return getContextualType(parent); case SyntaxKind.JsxExpression: + return getContextualType(parent); + case SyntaxKind.JsxAttribute: case SyntaxKind.JsxSpreadAttribute: - return getContextualTypeForJsxExpression(parent); + return getContextualTypeForJsxAttribute(parent); } return undefined; } From 6c8bb639393266cc44141670baec4dfc040eefe2 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 23 Dec 2015 17:10:54 -0800 Subject: [PATCH 4/4] Accepted baselines. --- ...ypedStringLiteralsInJsxAttributes01.errors.txt | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.errors.txt b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.errors.txt index 99bb5d6daf5..b5d4e01b677 100644 --- a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.errors.txt +++ b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes01.errors.txt @@ -1,12 +1,10 @@ -tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx(11,15): error TS2322: Type 'string' is not assignable to type '"A" | "B" | "C"'. - Type 'string' is not assignable to type '"C"'. tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx(13,15): error TS2322: Type '"f"' is not assignable to type '"A" | "B" | "C"'. Type '"f"' is not assignable to type '"C"'. -tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx(14,15): error TS2322: Type 'string' is not assignable to type '"A" | "B" | "C"'. - Type 'string' is not assignable to type '"C"'. +tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx(14,15): error TS2322: Type '"f"' is not assignable to type '"A" | "B" | "C"'. + Type '"f"' is not assignable to type '"C"'. -==== tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx (3 errors) ==== +==== tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStringLiteralsInJsxAttributes01.tsx (2 errors) ==== namespace JSX { interface IntrinsicElements { @@ -18,9 +16,6 @@ tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStr ; ; - ~~~~~~~ -!!! error TS2322: Type 'string' is not assignable to type '"A" | "B" | "C"'. -!!! error TS2322: Type 'string' is not assignable to type '"C"'. ; ~~~~~~~~~ @@ -28,5 +23,5 @@ tests/cases/conformance/types/contextualTypes/jsxAttributes/contextuallyTypedStr !!! error TS2322: Type '"f"' is not assignable to type '"C"'. ; ~~~~~~~ -!!! error TS2322: Type 'string' is not assignable to type '"A" | "B" | "C"'. -!!! error TS2322: Type 'string' is not assignable to type '"C"'. \ No newline at end of file +!!! error TS2322: Type '"f"' is not assignable to type '"A" | "B" | "C"'. +!!! error TS2322: Type '"f"' is not assignable to type '"C"'. \ No newline at end of file