From 26962dec656775aabf146cf830b06764abdf0234 Mon Sep 17 00:00:00 2001 From: Phips Peter Date: Tue, 23 Sep 2014 15:47:06 -0700 Subject: [PATCH] Got props types to work --- react/react-tests.ts | 71 ++++++++++++++++++++++++++++++++++++++++++++ react/react.d.ts | 56 ++++++++++++++++++++-------------- 2 files changed, 104 insertions(+), 23 deletions(-) create mode 100644 react/react-tests.ts diff --git a/react/react-tests.ts b/react/react-tests.ts new file mode 100644 index 000000000..bf60df67c --- /dev/null +++ b/react/react-tests.ts @@ -0,0 +1,71 @@ +/// +import React = require("react"); + +var PropTypesSpecification: React.Specification = { + propTypes: { + // You can declare that a prop is a specific JS primitive. By default, these + // are all optional. + optionalArray: React.PropTypes.array, + optionalBool: React.PropTypes.bool, + optionalFunc: React.PropTypes.func, + optionalNumber: React.PropTypes.number, + optionalObject: React.PropTypes.object, + optionalString: React.PropTypes.string, + + // Anything that can be rendered: numbers, strings, components or an array + // containing these types. + optionalRenderable: React.PropTypes.renderable, + + // A React component. + optionalComponent: React.PropTypes.component, + + // You can also declare that a prop is an instance of a class. This uses + // JS's instanceof operator. + optionalMessage: React.PropTypes.instanceOf(Date), + + // You can ensure that your prop is limited to specific values by treating + // it as an enum. + optionalEnum: React.PropTypes.oneOf(['News', 'Photos']), + + // An object that could be one of many types + optionalUnion: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.number, + React.PropTypes.instanceOf(Date) + ]), + + // An array of a certain type + optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number), + + // An object with property values of a certain type + optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number), + + // An object taking on a particular shape + optionalObjectWithShape: React.PropTypes.shape({ + color: React.PropTypes.string, + fontSize: React.PropTypes.number + }), + + // You can chain any of the above with `isRequired` to make sure a warning + // is shown if the prop isn't provided. + requiredFunc: React.PropTypes.func.isRequired, + + // A value of any data type + requiredAny: React.PropTypes.any.isRequired, + + // You can also specify a custom validator. It should return an Error + // object if the validation fails. Don't `console.warn` or throw, as this + // won't work inside `oneOfType`. + customProp: function(props, propName, componentName) { + if (!/matchme/.test(props[propName])) { + return new Error('Validation failed!'); + } + return null; + } + }, + render(): React.Descriptor { + return null; + } +}; + +React.createClass(PropTypesSpecification); \ No newline at end of file diff --git a/react/react.d.ts b/react/react.d.ts index 1166863f3..e9fc495fb 100644 --- a/react/react.d.ts +++ b/react/react.d.ts @@ -31,21 +31,22 @@ declare module "react" { componentWillUnmount?(): void; } - interface FunctionMap { - [key: string]: Function - } - export interface Specification extends Mixin { displayName?: string; mixins?: Mixin[]; - statics?: FunctionMap; - propTypes?: FunctionMap; + statics?: { + [key: string]: Function; + }; + propTypes?: ValidationMap

; getDefaultProps?(): P; getInitialState?(): S; render(): Descriptor; } export interface Component { + // TODO: Refs + props: P; + state: S; setState(nextState: S, callback?: () => void): void; replaceState(nextState: S, callback?: () => void): void; forceUpdate(callback?: () => void): void; @@ -60,25 +61,34 @@ declare module "react" { new(): any; } - interface Requireable extends Function { - isRequired: Function; + interface Validator

{ + (props: P, propName: string, componentName: string): Error; } - export var PropsTypes: { - any: Requireable; - array: Requireable; - bool: Requireable; - func: Requireable; - number: Requireable; - object: Requireable; - string: Requireable; - renderable: Requireable; - component: Requireable; - instanceOf: (clazz: Constructable) => Requireable; - oneOf: (types: any[]) => Requireable; - oneOfType: (types: Function[]) => Requireable; - arrayOf: (type: Function) => Requireable; - shape: (type: FunctionMap) => Requireable; + interface Requireable

extends Validator

{ + isRequired: Validator

; + } + + interface ValidationMap

{ + [key: string]: Validator

; + } + + export var PropTypes: { + any: Requireable; + array: Requireable; + bool: Requireable; + func: Requireable; + number: Requireable; + object: Requireable; + string: Requireable; + renderable: Requireable; + component: Requireable; + instanceOf: (clazz: Constructable) => Requireable; + oneOf: (types: any[]) => Requireable + oneOfType: (types: Validator[]) => Requireable; + arrayOf: (type: Validator) => Requireable; + objectOf: (type: Validator) => Requireable; + shape: (type: ValidationMap) => Requireable; }; export var Children: {