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.
This commit is contained in:
Nathan Shively-Sanders
2017-02-16 10:41:35 -08:00
parent c90040effb
commit bef1f9e87f
5 changed files with 87 additions and 3 deletions
+5 -3
View File
@@ -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; // <Elem attr /> is sugar for <Elem attr={true} />
trueType; // <Elem attr /> is sugar for <Elem attr={true} />
const attributeSymbol = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.name);
attributeSymbol.declarations = member.declarations;
@@ -12277,7 +12279,7 @@ namespace ts {
attributesTable = createMap<Symbol>();
}
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;
}
@@ -0,0 +1,30 @@
//// [spreadIntersectionJsx.tsx]
const React: any = null;
class A { a; }
class C { c; }
let intersected: A & C;
let element = <div { ...intersected } />;
//// [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));
@@ -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 = <div { ...intersected } />;
>element : Symbol(element, Decl(spreadIntersectionJsx.tsx, 4, 3))
>div : Symbol(unknown)
>intersected : Symbol(intersected, Decl(spreadIntersectionJsx.tsx, 3, 3))
@@ -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 = <div { ...intersected } />;
>element : any
><div { ...intersected } /> : any
>div : any
>intersected : A & C
@@ -0,0 +1,6 @@
// @jsx: react
const React: any = null;
class A { a; }
class C { c; }
let intersected: A & C;
let element = <div { ...intersected } />;