Merge pull request #3771 from RyanCavanaugh/fix3737

Fix bug #3737 (exported JSX classes props not validated)
This commit is contained in:
Ryan Cavanaugh
2015-07-07 17:54:36 -07:00
6 changed files with 201 additions and 11 deletions

View File

@@ -7095,14 +7095,17 @@ namespace ts {
// Look up the value in the current scope
if (node.tagName.kind === SyntaxKind.Identifier) {
valueSymbol = getResolvedSymbol(<Identifier>node.tagName);
let tag = <Identifier>node.tagName;
let sym = getResolvedSymbol(tag);
valueSymbol = sym.exportSymbol || sym;
}
else {
valueSymbol = checkQualifiedName(<QualifiedName>node.tagName).symbol;
}
if (valueSymbol !== unknownSymbol) {
if (valueSymbol && valueSymbol !== unknownSymbol) {
links.jsxFlags |= JsxFlags.ClassElement;
getSymbolLinks(valueSymbol).referenced = true;
}
return valueSymbol || unknownSymbol;
@@ -7311,15 +7314,6 @@ namespace ts {
let targetAttributesType = getJsxElementAttributesType(node);
if (getNodeLinks(node).jsxFlags & JsxFlags.ClassElement) {
if (node.tagName.kind === SyntaxKind.Identifier) {
checkIdentifier(<Identifier>node.tagName);
}
else {
checkQualifiedName(<QualifiedName>node.tagName);
}
}
let nameTable: Map<boolean> = {};
// Process this array in right-to-left order so we know which
// attributes (mostly from spreads) are being overwritten and

View File

@@ -0,0 +1,31 @@
tests/cases/conformance/jsx/file.tsx(9,14): error TS2322: Type 'number' is not assignable to type 'string'.
==== tests/cases/conformance/jsx/react.d.ts (0 errors) ====
declare module JSX {
interface Element { }
interface IntrinsicElements {
}
interface ElementAttributesProperty {
props;
}
}
interface Props {
foo: string;
}
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
export class MyComponent {
render() {
}
props: { foo: string; }
}
<MyComponent foo="bar" />; // ok
<MyComponent foo={0} />; // should be an error
~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.

View File

@@ -0,0 +1,42 @@
//// [tests/cases/conformance/jsx/tsxAttributeResolution9.tsx] ////
//// [react.d.ts]
declare module JSX {
interface Element { }
interface IntrinsicElements {
}
interface ElementAttributesProperty {
props;
}
}
interface Props {
foo: string;
}
//// [file.tsx]
export class MyComponent {
render() {
}
props: { foo: string; }
}
<MyComponent foo="bar" />; // ok
<MyComponent foo={0} />; // should be an error
//// [file.jsx]
define(["require", "exports"], function (require, exports) {
var MyComponent = (function () {
function MyComponent() {
}
MyComponent.prototype.render = function () {
};
return MyComponent;
})();
exports.MyComponent = MyComponent;
<MyComponent foo="bar"/>; // ok
<MyComponent foo={0}/>; // should be an error
});

View File

@@ -0,0 +1,47 @@
=== tests/cases/conformance/jsx/react.d.ts ===
declare module JSX {
>JSX : Symbol(JSX, Decl(react.d.ts, 0, 0))
interface Element { }
>Element : Symbol(Element, Decl(react.d.ts, 1, 20))
interface IntrinsicElements {
>IntrinsicElements : Symbol(IntrinsicElements, Decl(react.d.ts, 2, 22))
}
interface ElementAttributesProperty {
>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(react.d.ts, 4, 2))
props;
>props : Symbol(props, Decl(react.d.ts, 5, 38))
}
}
interface Props {
>Props : Symbol(Props, Decl(react.d.ts, 8, 1))
foo: string;
>foo : Symbol(foo, Decl(react.d.ts, 10, 17))
}
=== tests/cases/conformance/jsx/file.tsx ===
export class MyComponent {
>MyComponent : Symbol(MyComponent, Decl(file.tsx, 0, 0))
render() {
>render : Symbol(render, Decl(file.tsx, 0, 26))
}
props: { foo: string; }
>props : Symbol(props, Decl(file.tsx, 2, 3))
>foo : Symbol(foo, Decl(file.tsx, 4, 10))
}
<MyComponent foo="bar" />; // ok
>MyComponent : Symbol(MyComponent, Decl(file.tsx, 0, 0))
>foo : Symbol(unknown)
<MyComponent foo={0} />; // should be an error
>MyComponent : Symbol(MyComponent, Decl(file.tsx, 0, 0))
>foo : Symbol(unknown)

View File

@@ -0,0 +1,49 @@
=== tests/cases/conformance/jsx/react.d.ts ===
declare module JSX {
>JSX : any
interface Element { }
>Element : Element
interface IntrinsicElements {
>IntrinsicElements : IntrinsicElements
}
interface ElementAttributesProperty {
>ElementAttributesProperty : ElementAttributesProperty
props;
>props : any
}
}
interface Props {
>Props : Props
foo: string;
>foo : string
}
=== tests/cases/conformance/jsx/file.tsx ===
export class MyComponent {
>MyComponent : MyComponent
render() {
>render : () => void
}
props: { foo: string; }
>props : { foo: string; }
>foo : string
}
<MyComponent foo="bar" />; // ok
><MyComponent foo="bar" /> : JSX.Element
>MyComponent : typeof MyComponent
>foo : any
<MyComponent foo={0} />; // should be an error
><MyComponent foo={0} /> : JSX.Element
>MyComponent : typeof MyComponent
>foo : any

View File

@@ -0,0 +1,27 @@
//@jsx: preserve
//@module: amd
//@filename: react.d.ts
declare module JSX {
interface Element { }
interface IntrinsicElements {
}
interface ElementAttributesProperty {
props;
}
}
interface Props {
foo: string;
}
//@filename: file.tsx
export class MyComponent {
render() {
}
props: { foo: string; }
}
<MyComponent foo="bar" />; // ok
<MyComponent foo={0} />; // should be an error