From bef1f9e87f1c21c0884e3ad5c3d4cd7667405b94 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 16 Feb 2017 10:41:35 -0800 Subject: [PATCH] call isValidSpreadType in createJsxAttributesTypeFromAttributesProperty Previously, it only check for object and any types. This was the old check, so this change updates it to use isValidSpreadType. --- src/compiler/checker.ts | 8 +++-- .../reference/spreadIntersectionJsx.js | 30 +++++++++++++++++++ .../reference/spreadIntersectionJsx.symbols | 22 ++++++++++++++ .../reference/spreadIntersectionJsx.types | 24 +++++++++++++++ .../cases/compiler/spreadIntersectionJsx.tsx | 6 ++++ 5 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/spreadIntersectionJsx.js create mode 100644 tests/baselines/reference/spreadIntersectionJsx.symbols create mode 100644 tests/baselines/reference/spreadIntersectionJsx.types create mode 100644 tests/cases/compiler/spreadIntersectionJsx.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 11f3fb99380..cae13a5e78f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12241,10 +12241,12 @@ namespace ts { /** * Get attributes type of the JSX opening-like element. The result is from resolving "attributes" property of the opening-like element. - * + * * @param openingLikeElement a JSX opening-like element * @param filter a function to remove attributes that will not participate in checking whether attributes are assignable * @return an anonymous type (similar to the one returned by checkObjectLiteral) in which its properties are attributes property. + * @remarks Because this function calls getSpreadType, it needs to use the same checks as checkObjectLiteral, + * which also calls getSpreadType. */ function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, filter?: (symbol: Symbol) => boolean, contextualMapper?: TypeMapper) { const attributes = openingLikeElement.attributes; @@ -12256,7 +12258,7 @@ namespace ts { if (isJsxAttribute(attributeDecl)) { const exprType = attributeDecl.initializer ? checkExpression(attributeDecl.initializer, contextualMapper) : - trueType; // is sugar for + trueType; // is sugar for const attributeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.name); attributeSymbol.declarations = member.declarations; @@ -12277,7 +12279,7 @@ namespace ts { attributesTable = createMap(); } const exprType = checkExpression(attributeDecl.expression); - if (!(exprType.flags & (TypeFlags.Object | TypeFlags.Any))) { + if (!isValidSpreadType(exprType)) { error(attributeDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types); return anyType; } diff --git a/tests/baselines/reference/spreadIntersectionJsx.js b/tests/baselines/reference/spreadIntersectionJsx.js new file mode 100644 index 00000000000..9ba086dd765 --- /dev/null +++ b/tests/baselines/reference/spreadIntersectionJsx.js @@ -0,0 +1,30 @@ +//// [spreadIntersectionJsx.tsx] +const React: any = null; +class A { a; } +class C { c; } +let intersected: A & C; +let element =
; + + +//// [spreadIntersectionJsx.js] +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var React = null; +var A = (function () { + function A() { + } + return A; +}()); +var C = (function () { + function C() { + } + return C; +}()); +var intersected; +var element = React.createElement("div", __assign({}, intersected)); diff --git a/tests/baselines/reference/spreadIntersectionJsx.symbols b/tests/baselines/reference/spreadIntersectionJsx.symbols new file mode 100644 index 00000000000..24d7c90be1f --- /dev/null +++ b/tests/baselines/reference/spreadIntersectionJsx.symbols @@ -0,0 +1,22 @@ +=== tests/cases/compiler/spreadIntersectionJsx.tsx === +const React: any = null; +>React : Symbol(React, Decl(spreadIntersectionJsx.tsx, 0, 5)) + +class A { a; } +>A : Symbol(A, Decl(spreadIntersectionJsx.tsx, 0, 24)) +>a : Symbol(A.a, Decl(spreadIntersectionJsx.tsx, 1, 9)) + +class C { c; } +>C : Symbol(C, Decl(spreadIntersectionJsx.tsx, 1, 14)) +>c : Symbol(C.c, Decl(spreadIntersectionJsx.tsx, 2, 9)) + +let intersected: A & C; +>intersected : Symbol(intersected, Decl(spreadIntersectionJsx.tsx, 3, 3)) +>A : Symbol(A, Decl(spreadIntersectionJsx.tsx, 0, 24)) +>C : Symbol(C, Decl(spreadIntersectionJsx.tsx, 1, 14)) + +let element =
; +>element : Symbol(element, Decl(spreadIntersectionJsx.tsx, 4, 3)) +>div : Symbol(unknown) +>intersected : Symbol(intersected, Decl(spreadIntersectionJsx.tsx, 3, 3)) + diff --git a/tests/baselines/reference/spreadIntersectionJsx.types b/tests/baselines/reference/spreadIntersectionJsx.types new file mode 100644 index 00000000000..4756f73c5af --- /dev/null +++ b/tests/baselines/reference/spreadIntersectionJsx.types @@ -0,0 +1,24 @@ +=== tests/cases/compiler/spreadIntersectionJsx.tsx === +const React: any = null; +>React : any +>null : null + +class A { a; } +>A : A +>a : any + +class C { c; } +>C : C +>c : any + +let intersected: A & C; +>intersected : A & C +>A : A +>C : C + +let element =
; +>element : any +>
: any +>div : any +>intersected : A & C + diff --git a/tests/cases/compiler/spreadIntersectionJsx.tsx b/tests/cases/compiler/spreadIntersectionJsx.tsx new file mode 100644 index 00000000000..a46220db1c5 --- /dev/null +++ b/tests/cases/compiler/spreadIntersectionJsx.tsx @@ -0,0 +1,6 @@ +// @jsx: react +const React: any = null; +class A { a; } +class C { c; } +let intersected: A & C; +let element =
;