mirror of
https://github.com/gosticks/DefinitelyTyped.git
synced 2026-06-28 22:30:01 +00:00
Add more of the new features added in React 16.6 (#30054)
* Add definitions for React.memo
* Add missing semicolons
* Give a better name to the second argument to React.memo
* Fix test to reflect correct usage of React.memo's second argument
* Fix no-unnecessary-qualifier lints
* Update other special components to be SpecialSFC
* Ensure ordinary functions aren't assignable to SpecialSFC
* createElement was resolving P to "{} | null" in some tests; add extends to prevent that
* Fix the props of Fragment and StrictMode
* Add tests for SpecialSFC assignability
* Add scary doc comment to SpecialSFC's call signature
Hopefully this trips tslint's deprecation rule.
* Rename SpecialSFC to ExoticComponent
* Add overload to React.memo to make it more ergonomic and avoid implicit any
* Disable test that requires TS 3.1
* Add support for displayName in the exotic components that support it
* Tone down the call signature's doc comment
* Correct $ExpectType assertion
* Try to implement LibraryManagedAttributes for the ExoticComponents that should support them
This doesn't actually work because it seems only class components get them checked?
* Add type definitions for new React 16.6 features
This also attempts to add support for LibraryManagedAttributes to the ExoticComponents.
* The fallback prop is required by Suspense
* Declare legacy context on tests that use legacy context
This commit is contained in:
committed by
John Reilly
parent
a161857494
commit
9039892f8e
@@ -89,6 +89,7 @@ export class ArrowKeyStepperExample extends PureComponent<any, any> {
|
||||
import { List } from "react-virtualized";
|
||||
|
||||
export class AutoSizerExample extends PureComponent<any, any> {
|
||||
context: any;
|
||||
state: any;
|
||||
render() {
|
||||
const { list } = this.context;
|
||||
@@ -200,6 +201,7 @@ const GUTTER_SIZE = 3;
|
||||
const CELL_WIDTH = 75;
|
||||
|
||||
export class CollectionExample extends PureComponent<any, any> {
|
||||
context: any;
|
||||
state: any;
|
||||
_columnYMap: any;
|
||||
|
||||
@@ -372,6 +374,7 @@ export class ColumnSizerExample extends PureComponent<any, any> {
|
||||
}
|
||||
|
||||
export class GridExample extends PureComponent<any, any> {
|
||||
context: any;
|
||||
state = {
|
||||
columnCount: 1000,
|
||||
height: 300,
|
||||
@@ -511,7 +514,7 @@ const STATUS_LOADING = 1;
|
||||
const STATUS_LOADED = 2;
|
||||
|
||||
export class InfiniteLoaderExample extends PureComponent<any, any> {
|
||||
|
||||
context: any;
|
||||
state: any;
|
||||
_timeoutIds = new Set<number>();
|
||||
|
||||
@@ -619,6 +622,7 @@ export class InfiniteLoaderExample extends PureComponent<any, any> {
|
||||
}
|
||||
|
||||
export class ListExample extends PureComponent<any, any> {
|
||||
context: any;
|
||||
state: any;
|
||||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
@@ -758,6 +762,7 @@ export class GridExample2 extends PureComponent<any, any> {
|
||||
_cellPositioner: Positioner;
|
||||
_masonry: Masonry;
|
||||
|
||||
context: any;
|
||||
state: any;
|
||||
|
||||
constructor(props: any, context: any) {
|
||||
@@ -1256,6 +1261,7 @@ function mixColors(color1: any, color2: any, amount: any) {
|
||||
import { Column, Table, SortDirection, SortIndicator } from "react-virtualized";
|
||||
|
||||
export class TableExample extends PureComponent<{}, any> {
|
||||
context: any;
|
||||
state = {
|
||||
disableHeader: false,
|
||||
headerHeight: 30,
|
||||
@@ -1498,6 +1504,7 @@ export class DynamicHeightTableColumnExample extends PureComponent<any, any> {
|
||||
|
||||
export class WindowScrollerExample extends PureComponent<{}, any> {
|
||||
_windowScroller: WindowScroller;
|
||||
context: any;
|
||||
state = {
|
||||
showHeaderText: true
|
||||
};
|
||||
|
||||
162
types/react/index.d.ts
vendored
162
types/react/index.d.ts
vendored
@@ -191,19 +191,19 @@ declare namespace React {
|
||||
...children: ReactNode[]): DOMElement<P, T>;
|
||||
|
||||
// Custom components
|
||||
function createElement<P>(
|
||||
function createElement<P extends {}>(
|
||||
type: SFC<P>,
|
||||
props?: Attributes & P | null,
|
||||
...children: ReactNode[]): SFCElement<P>;
|
||||
function createElement<P>(
|
||||
function createElement<P extends {}>(
|
||||
type: ClassType<P, ClassicComponent<P, ComponentState>, ClassicComponentClass<P>>,
|
||||
props?: ClassAttributes<ClassicComponent<P, ComponentState>> & P | null,
|
||||
...children: ReactNode[]): CElement<P, ClassicComponent<P, ComponentState>>;
|
||||
function createElement<P, T extends Component<P, ComponentState>, C extends ComponentClass<P>>(
|
||||
function createElement<P extends {}, T extends Component<P, ComponentState>, C extends ComponentClass<P>>(
|
||||
type: ClassType<P, T, C>,
|
||||
props?: ClassAttributes<T> & P | null,
|
||||
...children: ReactNode[]): CElement<P, T>;
|
||||
function createElement<P>(
|
||||
function createElement<P extends {}>(
|
||||
type: SFC<P> | ComponentClass<P> | string,
|
||||
props?: Attributes & P | null,
|
||||
...children: ReactNode[]): ReactElement<P>;
|
||||
@@ -255,11 +255,40 @@ declare namespace React {
|
||||
unstable_observedBits?: number;
|
||||
}
|
||||
|
||||
type Provider<T> = ComponentType<ProviderProps<T>>;
|
||||
type Consumer<T> = ComponentType<ConsumerProps<T>>;
|
||||
// TODO: similar to how Fragment is actually a symbol, the values returned from createContext,
|
||||
// forwardRef and memo are actually objects that are treated specially by the renderer; see:
|
||||
// https://github.com/facebook/react/blob/v16.6.0/packages/react/src/ReactContext.js#L35-L48
|
||||
// https://github.com/facebook/react/blob/v16.6.0/packages/react/src/forwardRef.js#L42-L45
|
||||
// https://github.com/facebook/react/blob/v16.6.0/packages/react/src/memo.js#L27-L31
|
||||
// However, we have no way of telling the JSX parser that it's a JSX element type or its props other than
|
||||
// by pretending to be a normal component.
|
||||
//
|
||||
// We don't just use ComponentType or SFC types because you are not supposed to attach statics to this
|
||||
// object, but rather to the original function.
|
||||
interface ExoticComponent<P = {}> {
|
||||
/**
|
||||
* **NOTE**: Exotic components are not callable.
|
||||
*/
|
||||
(props: P): (ReactElement<any>|null);
|
||||
readonly $$typeof: symbol;
|
||||
}
|
||||
|
||||
interface NamedExoticComponent<P = {}> extends ExoticComponent<P> {
|
||||
displayName?: string;
|
||||
}
|
||||
|
||||
interface ProviderExoticComponent<P> extends ExoticComponent<P> {
|
||||
propTypes?: ValidationMap<P>;
|
||||
}
|
||||
|
||||
// NOTE: only the Context object itself can get a displayName
|
||||
// https://github.com/facebook/react-devtools/blob/e0b854e4c/backend/attachRendererFiber.js#L310-L325
|
||||
type Provider<T> = ProviderExoticComponent<ProviderProps<T>>;
|
||||
type Consumer<T> = ExoticComponent<ConsumerProps<T>>;
|
||||
interface Context<T> {
|
||||
Provider: Provider<T>;
|
||||
Consumer: Consumer<T>;
|
||||
displayName?: string;
|
||||
}
|
||||
function createContext<T>(
|
||||
defaultValue: T,
|
||||
@@ -269,8 +298,25 @@ declare namespace React {
|
||||
function isValidElement<P>(object: {} | null | undefined): object is ReactElement<P>;
|
||||
|
||||
const Children: ReactChildren;
|
||||
const Fragment: ComponentType;
|
||||
const StrictMode: ComponentType;
|
||||
const Fragment: ExoticComponent<{ children?: ReactNode }>;
|
||||
const StrictMode: ExoticComponent<{ children?: ReactNode }>;
|
||||
/**
|
||||
* This feature is not yet available for server-side rendering.
|
||||
* Suspense support will be added in a later release.
|
||||
*/
|
||||
const Suspense: ExoticComponent<{
|
||||
children?: ReactNode
|
||||
|
||||
/** A fallback react tree to show when a Suspense child (like React.lazy) suspends */
|
||||
fallback: NonNullable<ReactNode>|null
|
||||
|
||||
// I tried looking at the code but I have no idea what it does.
|
||||
// https://github.com/facebook/react/issues/13206#issuecomment-432489986
|
||||
/**
|
||||
* Not implemented yet, requires unstable_ConcurrentMode
|
||||
*/
|
||||
// maxDuration?: number
|
||||
}>;
|
||||
const version: string;
|
||||
|
||||
//
|
||||
@@ -283,6 +329,29 @@ declare namespace React {
|
||||
// tslint:disable-next-line:no-empty-interface
|
||||
interface Component<P = {}, S = {}, SS = any> extends ComponentLifecycle<P, S, SS> { }
|
||||
class Component<P, S> {
|
||||
// tslint won't let me format the sample code in a way that vscode likes it :(
|
||||
/**
|
||||
* If set, `this.context` will be set at runtime to the current value of the given Context.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* ```ts
|
||||
* type MyContext = number
|
||||
* const Ctx = React.createContext<MyContext>(0)
|
||||
*
|
||||
* class Foo extends React.Component {
|
||||
* static contextType = Ctx
|
||||
* context!: MyContext
|
||||
* render () {
|
||||
* return <>My context's value: {this.context}</>;
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @see https://reactjs.org/docs/context.html#classcontexttype
|
||||
*/
|
||||
static contextType?: Context<any>;
|
||||
|
||||
constructor(props: Readonly<P>);
|
||||
/**
|
||||
* @deprecated
|
||||
@@ -308,11 +377,6 @@ declare namespace React {
|
||||
// on the existence of `children` in `P`, then we should remove this.
|
||||
readonly props: Readonly<{ children?: ReactNode }> & Readonly<P>;
|
||||
state: Readonly<S>;
|
||||
/**
|
||||
* @deprecated
|
||||
* https://reactjs.org/docs/legacy-context.html
|
||||
*/
|
||||
context: any;
|
||||
/**
|
||||
* @deprecated
|
||||
* https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs
|
||||
@@ -417,6 +481,7 @@ declare namespace React {
|
||||
// Unfortunately, we have no way of declaring that the component constructor must implement this
|
||||
interface StaticLifecycle<P, S> {
|
||||
getDerivedStateFromProps?: GetDerivedStateFromProps<P, S>;
|
||||
getDerivedStateFromError?: GetDerivedStateFromError<P, S>;
|
||||
}
|
||||
|
||||
type GetDerivedStateFromProps<P, S> =
|
||||
@@ -427,6 +492,15 @@ declare namespace React {
|
||||
*/
|
||||
(nextProps: Readonly<P>, prevState: S) => Partial<S> | null;
|
||||
|
||||
type GetDerivedStateFromError<P, S> =
|
||||
/**
|
||||
* This lifecycle is invoked after an error has been thrown by a descendant component.
|
||||
* It receives the error that was thrown as a parameter and should return a value to update state.
|
||||
*
|
||||
* Note: its presence prevents any of the deprecated lifecycle methods from being invoked
|
||||
*/
|
||||
(error: any) => Partial<S> | null;
|
||||
|
||||
// This should be "infer SS" but can't use it yet
|
||||
interface NewLifecycle<P, S, SS> {
|
||||
/**
|
||||
@@ -558,7 +632,45 @@ declare namespace React {
|
||||
|
||||
function createRef<T>(): RefObject<T>;
|
||||
|
||||
function forwardRef<T, P = {}>(Component: RefForwardingComponent<T, P>): ComponentType<P & ClassAttributes<T>>;
|
||||
// will show `ForwardRef(${Component.displayName || Component.name})` in devtools by default,
|
||||
// but can be given its own specific name
|
||||
interface ForwardRefExoticComponent<P> extends NamedExoticComponent<P> {
|
||||
defaultProps?: Partial<P>;
|
||||
}
|
||||
|
||||
function forwardRef<T, P = {}>(Component: RefForwardingComponent<T, P>): ForwardRefExoticComponent<P & ClassAttributes<T>>;
|
||||
|
||||
type ComponentProps<T extends ComponentType<any>> =
|
||||
T extends ComponentType<infer P> ? P : {};
|
||||
type ComponentPropsWithRef<T extends ComponentType<any>> =
|
||||
T extends ComponentClass<infer P>
|
||||
? P & ClassAttributes<InstanceType<T>>
|
||||
: T extends SFC<infer P>
|
||||
? P
|
||||
: {};
|
||||
|
||||
// will show `Memo(${Component.displayName || Component.name})` in devtools by default,
|
||||
// but can be given its own specific name
|
||||
interface MemoExoticComponent<T extends ComponentType<any>> extends NamedExoticComponent<ComponentPropsWithRef<T>> {
|
||||
readonly type: T;
|
||||
}
|
||||
|
||||
function memo<P extends object>(
|
||||
Component: SFC<P>,
|
||||
propsAreEqual?: (prevProps: Readonly<P & { children?: ReactNode }>, nextProps: Readonly<P & { children?: ReactNode }>) => boolean
|
||||
): NamedExoticComponent<P>;
|
||||
function memo<T extends ComponentType<any>>(
|
||||
Component: T,
|
||||
propsAreEqual?: (prevProps: Readonly<ComponentProps<T>>, nextProps: Readonly<ComponentProps<T>>) => boolean
|
||||
): MemoExoticComponent<T>;
|
||||
|
||||
interface LazyExoticComponent<T extends ComponentType<any>> extends ExoticComponent<ComponentPropsWithRef<T>> {
|
||||
readonly _result: T;
|
||||
}
|
||||
|
||||
function lazy<T extends ComponentType<any>>(
|
||||
factory: () => Promise<{ default: T }>
|
||||
): LazyExoticComponent<T>;
|
||||
|
||||
//
|
||||
// React Hooks
|
||||
@@ -2460,6 +2572,14 @@ type Defaultize<P, D> = P extends any
|
||||
& Partial<Pick<D, Exclude<keyof D, keyof P>>>
|
||||
: never;
|
||||
|
||||
type ReactManagedAttributes<C, P> = C extends { propTypes: infer T; defaultProps: infer D; }
|
||||
? Defaultize<MergePropTypes<P, PropTypes.InferProps<T>>, D>
|
||||
: C extends { propTypes: infer T; }
|
||||
? MergePropTypes<P, PropTypes.InferProps<T>>
|
||||
: C extends { defaultProps: infer D; }
|
||||
? Defaultize<P, D>
|
||||
: P;
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
// tslint:disable-next-line:no-empty-interface
|
||||
@@ -2470,13 +2590,13 @@ declare global {
|
||||
interface ElementAttributesProperty { props: {}; }
|
||||
interface ElementChildrenAttribute { children: {}; }
|
||||
|
||||
type LibraryManagedAttributes<C, P> = C extends { propTypes: infer T; defaultProps: infer D; }
|
||||
? Defaultize<MergePropTypes<P, PropTypes.InferProps<T>>, D>
|
||||
: C extends { propTypes: infer T; }
|
||||
? MergePropTypes<P, PropTypes.InferProps<T>>
|
||||
: C extends { defaultProps: infer D; }
|
||||
? Defaultize<P, D>
|
||||
: P;
|
||||
// We can't recurse forever because `type` can't be self-referential;
|
||||
// let's assume it's reasonable to do a single React.lazy() around a single React.memo() / vice-versa
|
||||
type LibraryManagedAttributes<C, P> = C extends React.MemoExoticComponent<infer T> | React.LazyExoticComponent<infer T>
|
||||
? T extends React.MemoExoticComponent<infer U> | React.LazyExoticComponent<infer U>
|
||||
? ReactManagedAttributes<U, P>
|
||||
: ReactManagedAttributes<T, P>
|
||||
: ReactManagedAttributes<C, P>;
|
||||
|
||||
// tslint:disable-next-line:no-empty-interface
|
||||
interface IntrinsicAttributes extends React.Attributes { }
|
||||
|
||||
@@ -715,3 +715,18 @@ class RenderChildren extends React.Component {
|
||||
return children !== undefined ? children : null;
|
||||
}
|
||||
}
|
||||
|
||||
const Memoized1 = React.memo(function Foo(props: { foo: string }) { return null; });
|
||||
React.createElement(Memoized1, { foo: 'string' });
|
||||
|
||||
const Memoized2 = React.memo(
|
||||
function Bar(props: { bar: string }) { return null; },
|
||||
(prevProps, nextProps) => prevProps.bar === nextProps.bar
|
||||
);
|
||||
React.createElement(Memoized2, { bar: 'string' });
|
||||
|
||||
const specialSfc1: React.ExoticComponent<any> = Memoized1;
|
||||
const sfc: React.SFC<any> = Memoized2;
|
||||
// this $ExpectError is failing on TypeScript@next
|
||||
// // $ExpectError Property '$$typeof' is missing in type
|
||||
// const specialSfc2: React.SpecialSFC = props => null;
|
||||
|
||||
@@ -5,12 +5,12 @@ interface LeaveMeAloneDtslint { foo: string; }
|
||||
// import * as PropTypes from 'prop-types';
|
||||
|
||||
// interface Props {
|
||||
// bool?: boolean
|
||||
// fnc: () => any
|
||||
// node?: React.ReactNode
|
||||
// num?: number
|
||||
// reqNode: NonNullable<React.ReactNode>
|
||||
// str: string
|
||||
// bool?: boolean;
|
||||
// fnc: () => any;
|
||||
// node?: React.ReactNode;
|
||||
// num?: number;
|
||||
// reqNode: NonNullable<React.ReactNode>;
|
||||
// str: string;
|
||||
// }
|
||||
|
||||
// const propTypes = {
|
||||
@@ -24,9 +24,9 @@ interface LeaveMeAloneDtslint { foo: string; }
|
||||
// };
|
||||
|
||||
// const defaultProps = {
|
||||
// fnc: function() { return 'abc' } as () => any,
|
||||
// fnc: (() => 'abc') as () => any,
|
||||
// extraBool: false,
|
||||
// reqNode: 'text_node' as React.ReactNode
|
||||
// reqNode: 'text_node' as NonNullable<React.ReactNode>
|
||||
// };
|
||||
|
||||
// class AnnotatedPropTypesAndDefaultProps extends React.Component<Props> {
|
||||
@@ -158,3 +158,67 @@ interface LeaveMeAloneDtslint { foo: string; }
|
||||
// reqNode={<span />}
|
||||
// />
|
||||
// ];
|
||||
|
||||
// class ComponentWithNoDefaultProps extends React.Component<Props> {}
|
||||
|
||||
// function FunctionalComponent(props: Props) { return <>{props.reqNode}</> }
|
||||
// FunctionalComponent.defaultProps = defaultProps;
|
||||
|
||||
// const functionalComponentTests = [
|
||||
// // $ExpectError
|
||||
// <FunctionalComponent />,
|
||||
// // This is possibly a bug/limitation of TS
|
||||
// // Even if JSX.LibraryManagedAttributes returns the correct type, it doesn't seem to work with non-classes
|
||||
// // This also doesn't work with things typed React.SFC<P> because defaultProps will always be Partial<P>
|
||||
// // $ExpectError
|
||||
// <FunctionalComponent str='' />
|
||||
// ];
|
||||
|
||||
// const MemoFunctionalComponent = React.memo(FunctionalComponent);
|
||||
// const MemoAnnotatedDefaultProps = React.memo(AnnotatedDefaultProps);
|
||||
// const LazyMemoFunctionalComponent = React.lazy(async () => ({ default: MemoFunctionalComponent }));
|
||||
// const LazyMemoAnnotatedDefaultProps = React.lazy(async () => ({ default: MemoAnnotatedDefaultProps }));
|
||||
|
||||
// const memoTests = [
|
||||
// // $ExpectError
|
||||
// <MemoFunctionalComponent />,
|
||||
// // $ExpectError won't work as long as FunctionalComponent doesn't work either
|
||||
// <MemoFunctionalComponent str='abc' />,
|
||||
// // $ExpectError
|
||||
// <MemoAnnotatedDefaultProps />,
|
||||
// <AnnotatedDefaultProps str='abc' />,
|
||||
// // $ExpectError this doesn't work despite JSX.LibraryManagedAttributes returning the correct type
|
||||
// <MemoAnnotatedDefaultProps str='abc' />,
|
||||
// // $ExpectError won't work as long as FunctionalComponent doesn't work either
|
||||
// <LazyMemoFunctionalComponent str='abc' />,
|
||||
// // $ExpectError
|
||||
// <LazyMemoAnnotatedDefaultProps />,
|
||||
// // $ExpectError this doesn't work despite JSX.LibraryManagedAttributes returning the correct type
|
||||
// <LazyMemoAnnotatedDefaultProps str='abc' />
|
||||
// ];
|
||||
|
||||
// type AnnotatedDefaultPropsLibraryManagedAttributes = JSX.LibraryManagedAttributes<typeof AnnotatedDefaultProps, Props>;
|
||||
// // $ExpectType AnnotatedDefaultPropsLibraryManagedAttributes
|
||||
// type FunctionalComponentLibraryManagedAttributes = JSX.LibraryManagedAttributes<typeof FunctionalComponent, Props>;
|
||||
// // $ExpectType FunctionalComponentLibraryManagedAttributes
|
||||
// type MemoFunctionalComponentLibraryManagedAttributes = JSX.LibraryManagedAttributes<typeof MemoFunctionalComponent, Props>;
|
||||
// // $ExpectType FunctionalComponentLibraryManagedAttributes
|
||||
// type LazyMemoFunctionalComponentLibraryManagedAttributes = JSX.LibraryManagedAttributes<typeof LazyMemoFunctionalComponent, Props>;
|
||||
|
||||
// const ForwardRef = React.forwardRef((props: Props, ref: React.Ref<ComponentWithNoDefaultProps>) => (
|
||||
// <ComponentWithNoDefaultProps ref={ref} {...props}/>
|
||||
// ));
|
||||
// ForwardRef.defaultProps = defaultProps;
|
||||
|
||||
// const forwardRefTests = [
|
||||
// // $ExpectError
|
||||
// <ForwardRef />,
|
||||
// <ForwardRef
|
||||
// fnc={console.log}
|
||||
// reqNode={<span />}
|
||||
// str=''
|
||||
// />,
|
||||
// // same bug as MemoFunctionalComponent and React.SFC-typed things
|
||||
// // $ExpectError the type of ForwardRef.defaultProps stays Partial<P> anyway even if assigned
|
||||
// <ForwardRef str='abc' />
|
||||
// ];
|
||||
|
||||
@@ -197,3 +197,60 @@ componentWithBadLifecycle.getSnapshotBeforeUpdate = () => { // $ExpectError
|
||||
componentWithBadLifecycle.componentDidUpdate = (prevProps: {}, prevState: {}, snapshot?: string) => { // $ExpectError
|
||||
return;
|
||||
};
|
||||
|
||||
const Memoized1 = React.memo(function Foo(props: { foo: string }) { return null; });
|
||||
<Memoized1 foo='string'/>;
|
||||
|
||||
const Memoized2 = React.memo(
|
||||
function Bar(props: { bar: string }) { return null; },
|
||||
(prevProps, nextProps) => prevProps.bar === nextProps.bar
|
||||
);
|
||||
<Memoized2 bar='string'/>;
|
||||
|
||||
const Memoized3 = React.memo(class Test extends React.Component<{ x?: string }> {});
|
||||
<Memoized3 ref={ref => { if (ref) { ref.props.x; } }}/>;
|
||||
|
||||
const memoized4Ref = React.createRef<HTMLDivElement>();
|
||||
const Memoized4 = React.memo(React.forwardRef((props: {}, ref: React.Ref<HTMLDivElement>) => <div ref={ref}/>));
|
||||
<Memoized4 ref={memoized4Ref}/>;
|
||||
|
||||
const Memoized5 = React.memo<{ test: boolean }>(
|
||||
prop => <>{prop.test && prop.children}</>,
|
||||
(prevProps, nextProps) => nextProps.test ? prevProps.children === nextProps.children : prevProps.test
|
||||
);
|
||||
|
||||
<Memoized5 test/>;
|
||||
|
||||
// for some reason the ExpectType doesn't work if the type is namespaced
|
||||
// $ExpectType NamedExoticComponent<{}>
|
||||
const Memoized6 = React.memo(props => null);
|
||||
<Memoized6/>;
|
||||
// $ExpectError
|
||||
<Memoized6 foo/>;
|
||||
|
||||
// NOTE: this test _requires_ TypeScript 3.1
|
||||
// It is passing, for what it's worth.
|
||||
// const Memoized7 = React.memo((() => {
|
||||
// function HasDefaultProps(props: { test: boolean }) { return null; }
|
||||
// HasDefaultProps.defaultProps = {
|
||||
// test: true
|
||||
// };
|
||||
// return HasDefaultProps;
|
||||
// })());
|
||||
// // $ExpectType boolean
|
||||
// Memoized7.type.defaultProps.test;
|
||||
|
||||
const LazyClassComponent = React.lazy(async () => ({ default: ComponentWithPropsAndState }));
|
||||
const LazyMemoized3 = React.lazy(async () => ({ default: Memoized3 }));
|
||||
const LazyRefForwarding = React.lazy(async () => ({ default: Memoized4 }));
|
||||
|
||||
<React.Suspense fallback={<Memoized1 foo='string' />}>
|
||||
<LazyClassComponent hello='test'/>
|
||||
<LazyClassComponent ref={ref => { if (ref) { ref.props.hello; } }} hello='test'/>
|
||||
<LazyMemoized3 ref={ref => { if (ref) { ref.props.x; } }}/>
|
||||
<LazyRefForwarding ref={memoized4Ref}/>
|
||||
</React.Suspense>;
|
||||
|
||||
<React.Suspense fallback={null}/>;
|
||||
// $ExpectError
|
||||
<React.Suspense/>;
|
||||
|
||||
@@ -54,6 +54,7 @@ function customWithTheme<P>(
|
||||
) {
|
||||
return class CustomWithTheme extends React.Component<P, { theme: object }> {
|
||||
static contextTypes = themeListener.contextTypes;
|
||||
context: any;
|
||||
|
||||
setTheme = (theme: object) => this.setState({ theme });
|
||||
subscription: number | undefined;
|
||||
|
||||
Reference in New Issue
Block a user