Merge pull request #14122 from Microsoft/jsx-spread-calls-isValidSpreadType

call isValidSpreadType in createJsxAttributesTypeFromAttributesProperty
This commit is contained in:
Nathan Shively-Sanders 2017-02-16 11:13:34 -08:00 committed by GitHub
commit 2e466c6d8f
5 changed files with 87 additions and 3 deletions

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;
}

View file

@ -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));

View file

@ -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))

View file

@ -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

View file

@ -0,0 +1,6 @@
// @jsx: react
const React: any = null;
class A { a; }
class C { c; }
let intersected: A & C;
let element = <div { ...intersected } />;