mirror of
https://github.com/wassname/DefinitelyTyped.git
synced 2026-09-09 11:13:57 +08:00
[React.14] Add StatelessComponent<P> and tests
- Also add image to JSX.IntrinsicElements - Add tests for callback and string refs - Fix bug where Component<P, S> subclasses are required to have defaultProps
This commit is contained in:
+60
-9
@@ -24,7 +24,6 @@ interface Props extends React.Props<MyComponent> {
|
||||
hello: string;
|
||||
world?: string;
|
||||
foo: number;
|
||||
bar: boolean;
|
||||
}
|
||||
|
||||
interface State {
|
||||
@@ -48,8 +47,7 @@ var props: Props = {
|
||||
key: 42,
|
||||
ref: "myComponent42",
|
||||
hello: "world",
|
||||
foo: 42,
|
||||
bar: true
|
||||
foo: 42
|
||||
};
|
||||
|
||||
var container: Element;
|
||||
@@ -61,11 +59,10 @@ var container: Element;
|
||||
var ClassicComponent: React.ClassicComponentClass<Props> =
|
||||
React.createClass<Props, State>({
|
||||
getDefaultProps() {
|
||||
return <Props>{
|
||||
return {
|
||||
hello: undefined,
|
||||
world: "peace",
|
||||
foo: undefined,
|
||||
bar: undefined,
|
||||
foo: undefined
|
||||
};
|
||||
},
|
||||
getInitialState() {
|
||||
@@ -87,7 +84,7 @@ var ClassicComponent: React.ClassicComponentClass<Props> =
|
||||
});
|
||||
|
||||
class ModernComponent extends React.Component<Props, State>
|
||||
implements React.ChildContextProvider<ChildContext> {
|
||||
implements MyComponent, React.ChildContextProvider<ChildContext> {
|
||||
|
||||
static propTypes: React.ValidationMap<Props> = {
|
||||
foo: React.PropTypes.number
|
||||
@@ -101,8 +98,6 @@ class ModernComponent extends React.Component<Props, State>
|
||||
someOtherValue: React.PropTypes.string
|
||||
}
|
||||
|
||||
static defaultProps: Props;
|
||||
|
||||
context: Context;
|
||||
|
||||
getChildContext() {
|
||||
@@ -117,12 +112,14 @@ class ModernComponent extends React.Component<Props, State>
|
||||
}
|
||||
|
||||
reset() {
|
||||
this._myComponent.reset();
|
||||
this.setState({
|
||||
inputValue: this.context.someValue,
|
||||
seconds: this.props.foo
|
||||
});
|
||||
}
|
||||
|
||||
private _myComponent: MyComponent;
|
||||
private _input: HTMLInputElement;
|
||||
|
||||
render() {
|
||||
@@ -134,12 +131,32 @@ class ModernComponent extends React.Component<Props, State>
|
||||
}
|
||||
}
|
||||
|
||||
interface SCProps extends React.Props<{}> {
|
||||
foo?: number;
|
||||
}
|
||||
|
||||
var StatelessComponent = (props: SCProps) => {
|
||||
return React.DOM.div(null, props.foo);
|
||||
};
|
||||
|
||||
// Must explicitly type-annotate to add defaultProps/contextTypes
|
||||
var StatelessComponent2: React.StatelessComponent<SCProps> =
|
||||
(props: SCProps) => React.DOM.div(null, props.foo);
|
||||
StatelessComponent2.defaultProps = {
|
||||
foo: 42
|
||||
};
|
||||
|
||||
// React.createFactory
|
||||
var factory: React.Factory<Props> =
|
||||
React.createFactory(ModernComponent);
|
||||
var factoryElement: React.ReactElement<Props> =
|
||||
factory(props);
|
||||
|
||||
var statelessFactory: React.Factory<SCProps> =
|
||||
React.createFactory(StatelessComponent);
|
||||
var statelessElement: React.ReactElement<SCProps> =
|
||||
statelessFactory(props);
|
||||
|
||||
var classicFactory: React.ClassicFactory<Props> =
|
||||
React.createFactory(ClassicComponent);
|
||||
var classicFactoryElement: React.ClassicElement<Props> =
|
||||
@@ -153,6 +170,8 @@ var domFactoryElement: React.DOMElement<any> =
|
||||
// React.createElement
|
||||
var element: React.ReactElement<Props> =
|
||||
React.createElement(ModernComponent, props);
|
||||
var statelessElement: React.ReactElement<SCProps> =
|
||||
React.createElement(StatelessComponent, props);
|
||||
var classicElement: React.ClassicElement<Props> =
|
||||
React.createElement(ClassicComponent, props);
|
||||
var domElement: React.ReactHTMLElement =
|
||||
@@ -161,6 +180,8 @@ var domElement: React.ReactHTMLElement =
|
||||
// React.cloneElement
|
||||
var clonedElement: React.ReactElement<Props> =
|
||||
React.cloneElement(element, props);
|
||||
var clonedStatelessElement: React.ReactElement<SCProps> =
|
||||
React.cloneElement(statelessElement, props);
|
||||
var clonedClassicElement: React.ClassicElement<Props> =
|
||||
React.cloneElement(classicElement, props);
|
||||
var clonedDOMElement: React.ReactHTMLElement =
|
||||
@@ -215,6 +236,36 @@ classicComponent.replaceState({ inputValue: "???", seconds: 60 });
|
||||
var myComponent = <MyComponent>component;
|
||||
myComponent.reset();
|
||||
|
||||
//
|
||||
// Refs
|
||||
// NB: to infer the correct type for callback refs, your component's Props
|
||||
// interface must extend React.Props<T> where T is your component type (or
|
||||
// an interface that it implements).
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
interface RCProps extends React.Props<RefComponent> {
|
||||
}
|
||||
|
||||
class RefComponent extends React.Component<RCProps, {}> {
|
||||
static create = React.createFactory(RefComponent);
|
||||
refMethod() {
|
||||
}
|
||||
}
|
||||
|
||||
var componentRef: RefComponent;
|
||||
RefComponent.create({ ref: "componentRef" });
|
||||
// type of c should be inferred
|
||||
RefComponent.create({ ref: c => componentRef = c });
|
||||
componentRef.refMethod();
|
||||
|
||||
var domNodeRef: Element;
|
||||
React.DOM.div({ ref: "domRef" });
|
||||
// type of node should be inferred
|
||||
React.DOM.div({ ref: node => domNodeRef = node });
|
||||
|
||||
var inputNodeRef: HTMLInputElement;
|
||||
React.DOM.input({ ref: node => inputNodeRef = <HTMLInputElement>node });
|
||||
|
||||
//
|
||||
// Attributes
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
Vendored
+19
-15
@@ -8,21 +8,21 @@ declare namespace __React {
|
||||
// React Elements
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
type ReactType = ComponentClass<any> | string;
|
||||
type ReactType = string | ComponentClass<any> | StatelessComponent<any>;
|
||||
|
||||
interface ReactElement<P> {
|
||||
type: string | ComponentClass<P>;
|
||||
interface ReactElement<P extends Props<any>> {
|
||||
type: string | ComponentClass<P> | StatelessComponent<P>;
|
||||
props: P;
|
||||
key: string | number;
|
||||
ref: string | ((component: Component<P, any> | Element) => any);
|
||||
}
|
||||
|
||||
interface ClassicElement<P> extends ReactElement<P> {
|
||||
type: string | ClassicComponentClass<P>;
|
||||
type: ClassicComponentClass<P>;
|
||||
ref: string | ((component: ClassicComponent<P, any>) => any);
|
||||
}
|
||||
|
||||
interface DOMElement<P> extends ReactElement<P> {
|
||||
interface DOMElement<P extends Props<Element>> extends ReactElement<P> {
|
||||
type: string;
|
||||
ref: string | ((element: Element) => any);
|
||||
}
|
||||
@@ -47,7 +47,7 @@ declare namespace __React {
|
||||
(props?: P, ...children: ReactNode[]): ClassicElement<P>;
|
||||
}
|
||||
|
||||
interface DOMFactory<P> extends ClassicFactory<P> {
|
||||
interface DOMFactory<P extends Props<Element>> extends Factory<P> {
|
||||
(props?: P, ...children: ReactNode[]): DOMElement<P>;
|
||||
}
|
||||
|
||||
@@ -73,19 +73,19 @@ declare namespace __React {
|
||||
function createClass<P, S>(spec: ComponentSpec<P, S>): ClassicComponentClass<P>;
|
||||
|
||||
function createFactory<P>(type: string): DOMFactory<P>;
|
||||
function createFactory<P>(type: ClassicComponentClass<P> | string): ClassicFactory<P>;
|
||||
function createFactory<P>(type: ComponentClass<P>): Factory<P>;
|
||||
function createFactory<P>(type: ClassicComponentClass<P>): ClassicFactory<P>;
|
||||
function createFactory<P>(type: ComponentClass<P> | StatelessComponent<P>): Factory<P>;
|
||||
|
||||
function createElement<P>(
|
||||
type: string,
|
||||
props?: P,
|
||||
...children: ReactNode[]): DOMElement<P>;
|
||||
function createElement<P>(
|
||||
type: ClassicComponentClass<P> | string,
|
||||
type: ClassicComponentClass<P>,
|
||||
props?: P,
|
||||
...children: ReactNode[]): ClassicElement<P>;
|
||||
function createElement<P>(
|
||||
type: ComponentClass<P>,
|
||||
type: ComponentClass<P> | StatelessComponent<P>,
|
||||
props?: P,
|
||||
...children: ReactNode[]): ReactElement<P>;
|
||||
|
||||
@@ -116,11 +116,6 @@ declare namespace __React {
|
||||
|
||||
// Base component for plain JS classes
|
||||
class Component<P, S> implements ComponentLifecycle<P, S> {
|
||||
static propTypes: ValidationMap<any>;
|
||||
static contextTypes: ValidationMap<any>;
|
||||
static childContextTypes: ValidationMap<any>;
|
||||
static defaultProps: Props<any>;
|
||||
|
||||
constructor(props?: P, context?: any);
|
||||
setState(f: (prevState: S, props: P) => S, callback?: () => any): void;
|
||||
setState(state: S, callback?: () => any): void;
|
||||
@@ -148,6 +143,13 @@ declare namespace __React {
|
||||
// Class Interfaces
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
interface StatelessComponent<P> {
|
||||
(props?: P, context?: any): ReactElement<any>;
|
||||
propTypes?: ValidationMap<P>;
|
||||
contextTypes?: ValidationMap<any>;
|
||||
defaultProps?: P;
|
||||
}
|
||||
|
||||
interface ComponentClass<P> {
|
||||
new(props?: P, context?: any): Component<P, any>;
|
||||
propTypes?: ValidationMap<P>;
|
||||
@@ -325,6 +327,7 @@ declare namespace __React {
|
||||
defaultChecked?: boolean;
|
||||
defaultValue?: string | string[];
|
||||
}
|
||||
|
||||
interface SVGProps extends SVGAttributes, Props<SVGElement> {
|
||||
}
|
||||
|
||||
@@ -1001,6 +1004,7 @@ declare namespace JSX {
|
||||
defs: React.SVGProps;
|
||||
ellipse: React.SVGProps;
|
||||
g: React.SVGProps;
|
||||
image: React.SVGProps;
|
||||
line: React.SVGProps;
|
||||
linearGradient: React.SVGProps;
|
||||
mask: React.SVGProps;
|
||||
|
||||
Reference in New Issue
Block a user