diff --git a/react/index.d.ts b/react/index.d.ts index 92aa3a03fc..8d5edbab51 100644 --- a/react/index.d.ts +++ b/react/index.d.ts @@ -28,7 +28,7 @@ declare namespace React { interface ReactElement

{ type: string | ComponentClass

| SFC

; props: P; - key?: Key; + key: Key | null; } interface SFCElement

extends ReactElement

{ @@ -74,7 +74,7 @@ declare namespace React { type ClassicFactory

= CFactory>; interface DOMFactory

, T extends Element> { - (props?: P & ClassAttributes, ...children: ReactNode[]): DOMElement; + (props?: P & ClassAttributes | null, ...children: ReactNode[]): DOMElement; } interface HTMLFactory extends DOMFactory, T> { @@ -93,7 +93,7 @@ declare namespace React { // Should be Array but type aliases cannot be recursive type ReactFragment = {} | Array; - type ReactNode = ReactChild | ReactFragment | boolean; + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; // // Top Level API @@ -201,7 +201,7 @@ declare namespace React { type SFC

= StatelessComponent

; interface StatelessComponent

{ - (props: P, context?: any): ReactElement | null; + (props: P, context?: any): ReactElement; propTypes?: ValidationMap

; contextTypes?: ValidationMap; defaultProps?: P; @@ -262,7 +262,7 @@ declare namespace React { } interface ComponentSpec extends Mixin { - render(): ReactElement; + render(): ReactElement | null; [propertyName: string]: any; } @@ -2354,7 +2354,7 @@ declare namespace React { // ---------------------------------------------------------------------- interface Validator { - (object: T, key: string, componentName: string, ...rest: any[]): Error; + (object: T, key: string, componentName: string, ...rest: any[]): Error | null; } interface Requireable extends Validator { diff --git a/react/react-tests.ts b/react/react-tests.ts index 85bc4c0704..7cdecd9e86 100644 --- a/react/react-tests.ts +++ b/react/react-tests.ts @@ -41,7 +41,7 @@ var props: Props & React.ClassAttributes<{}> = { foo: 42 }; -var container: Element; +var container: Element = document.createElement("div"); // // Top-Level API @@ -49,11 +49,12 @@ var container: Element; var ClassicComponent: React.ClassicComponentClass = React.createClass({ + displayName: "ClassicComponent", getDefaultProps() { return { - hello: undefined, + hello: "hello", world: "peace", - foo: undefined + foo: 0, }; }, getInitialState() { @@ -187,6 +188,10 @@ var domElement: React.ReactHTMLElement = // React.cloneElement var clonedElement: React.CElement = React.cloneElement(element, { foo: 43 }); + +React.cloneElement(element, {}); +React.cloneElement(element, {}, null); + var clonedElement2: React.CElement = // known problem: cloning with key or ref requires cast React.cloneElement(element, >{ @@ -240,18 +245,15 @@ domNode = ReactDOM.findDOMNode(domNode); var type: React.ComponentClass = element.type; var elementProps: Props = element.props; -var key: React.Key = element.key; - -var t: React.ReactType; -var name = typeof t === "string" ? t : t.displayName; +var key = element.key; // // React Components // -------------------------------------------------------------------------- -var displayName: string = ClassicComponent.displayName; -var defaultProps: Props = ClassicComponent.getDefaultProps(); -var propTypes: React.ValidationMap = ClassicComponent.propTypes; +var displayName: string | undefined = ClassicComponent.displayName; +var defaultProps: Props = ClassicComponent.getDefaultProps ? ClassicComponent.getDefaultProps() : {}; +var propTypes: React.ValidationMap | undefined = ClassicComponent.propTypes; // // Component API @@ -282,7 +284,7 @@ class RefComponent extends React.Component { } } -var componentRef: RefComponent; +var componentRef: RefComponent = new RefComponent(); RefComponent.create({ ref: "componentRef" }); // type of c should be inferred RefComponent.create({ ref: c => componentRef = c }); @@ -377,14 +379,14 @@ var PropTypesSpecification: React.ComponentSpec = { }), requiredFunc: React.PropTypes.func.isRequired, requiredAny: React.PropTypes.any.isRequired, - customProp: function(props: any, propName: string, componentName: string) { + customProp: function(props: any, propName: string, componentName: string): Error | null { if (!/matchme/.test(props[propName])) { return new Error("Validation failed!"); } return null; }, // https://facebook.github.io/react/warnings/dont-call-proptypes.html#fixing-the-false-positive-in-third-party-proptypes - percentage: (object: any, key: string, componentName: string, ...rest: any[]): Error => { + percentage: (object: any, key: string, componentName: string, ...rest: any[]): Error | null => { const error = React.PropTypes.number(object, key, componentName, ...rest); if (error) { return error; @@ -395,7 +397,7 @@ var PropTypesSpecification: React.ComponentSpec = { return null; } }, - render: (): React.ReactElement => { + render: (): React.ReactElement | null => { return null; } }; @@ -429,14 +431,14 @@ var ContextTypesSpecification: React.ComponentSpec = { }), requiredFunc: React.PropTypes.func.isRequired, requiredAny: React.PropTypes.any.isRequired, - customProp: function(props: any, propName: string, componentName: string) { + customProp: function(props: any, propName: string, componentName: string): Error | null { if (!/matchme/.test(props[propName])) { return new Error("Validation failed!"); } return null; } }, - render: (): React.ReactElement => { + render: (): null => { return null; } }; @@ -499,7 +501,7 @@ createFragment({ // -------------------------------------------------------------------------- React.createFactory(CSSTransitionGroup)({ component: React.createClass({ - render: (): React.ReactElement => null + render: (): null => null }), childFactory: (c) => c, transitionName: "transition", @@ -605,16 +607,19 @@ var foundComponents: ModernComponent[] = TestUtils.scryRenderedComponentsWithTyp // ReactTestUtils custom type guards -var emptyElement: React.ReactElement<{}>; -if (TestUtils.isElementOfType(emptyElement, StatelessComponent)) { - emptyElement.props.foo; +var emptyElement1: React.ReactElement<{}> = React.createElement(ModernComponent); +if (TestUtils.isElementOfType(emptyElement1, StatelessComponent)) { + emptyElement1.props.foo; +} +var emptyElement2: React.ReactElement<{}> = React.createElement(StatelessComponent); +if (TestUtils.isElementOfType(emptyElement2, StatelessComponent)) { + emptyElement2.props.foo; } -var anyInstance: Element | React.Component; -if (TestUtils.isDOMComponent(anyInstance)) { - anyInstance.getAttribute("className"); -} else if (TestUtils.isCompositeComponent(anyInstance)) { - anyInstance.props; +if (TestUtils.isDOMComponent(container)) { + container.getAttribute("className"); +} else if (TestUtils.isCompositeComponent(new ModernComponent())) { + new ModernComponent().props; } // @@ -655,4 +660,4 @@ class ConstructorSpreadArgsPureComponent extends React.PureComponent<{}, {}> { constructor(...args: any[]) { super(...args); } -} \ No newline at end of file +} diff --git a/react/tsconfig.json b/react/tsconfig.json index 55fd2537d4..d89fd3bdf7 100644 --- a/react/tsconfig.json +++ b/react/tsconfig.json @@ -8,7 +8,7 @@ "module": "commonjs", "target": "es6", "noImplicitAny": true, - "strictNullChecks": false, + "strictNullChecks": true, "baseUrl": "../", "typeRoots": [ "../"