Skip to content

Commit

Permalink
Add enhanced typings
Browse files Browse the repository at this point in the history
  • Loading branch information
as-com committed Mar 1, 2018
1 parent 4333ca7 commit 124d1cd
Show file tree
Hide file tree
Showing 8 changed files with 4,106 additions and 43 deletions.
4 changes: 2 additions & 2 deletions packages/inferno-compat/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { cloneVNode } from 'inferno-clone-vnode';
import { ClassicComponentClass, ComponentSpec, createClass } from 'inferno-create-class';
import { createElement } from 'inferno-create-element';
import { isArray, isBrowser, isFunction, isInvalid, isNull, isNullOrUndef, isString, NO_OP } from 'inferno-shared';
import { VNodeFlags} from 'inferno-vnode-flags';
import { VNodeFlags } from 'inferno-vnode-flags';
import { isValidElement } from './isValidElement';
import PropTypes from './PropTypes';
import { SVGDOMPropertyConfig } from './SVGDOMPropertyConfig';
Expand Down Expand Up @@ -275,7 +275,7 @@ class PureComponent<P, S> extends Component<P, S> {
class WrapperComponent<P, S> extends Component<P, S> {
public getChildContext() {
// tslint:disable-next-line
return this.props.context;
return (this.props as any).context; // TODO: Is this intentional???
}

public render(props) {
Expand Down
4 changes: 2 additions & 2 deletions packages/inferno-create-element/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function createElement<T>(type: string | Function | Component<any, any>,
let children: any = _children;
let ref: any = null;
let key = null;
let className = null;
let className: string | null = null;
let flags = 0;
let newProps;

Expand All @@ -44,7 +44,7 @@ export function createElement<T>(type: string | Function | Component<any, any>,

for (const prop in props) {
if (prop === 'className' || prop === 'class') {
className = props[prop];
className = (props as any)[prop];
} else if (prop === 'key') {
key = props.key;
} else if (prop === 'children' && isUndefined(children)) {
Expand Down
3 changes: 2 additions & 1 deletion packages/inferno-router/src/Switch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { Component, createComponentVNode, VNode } from 'inferno';
import { matchPath } from './matchPath';
import { Children, invariant, isValidElement, warning } from './utils';
import { combineFrom } from 'inferno-shared';
import { IRouteProps } from "./Route";

export interface ISwitchProps {
export interface ISwitchProps extends IRouteProps {
router: any;
children: Array<Component<any, any>>;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/inferno-router/src/withRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function withRouter(Com) {
const C: any = function(props: IWithRouterProps) {
const { wrappedComponentRef, ...remainingProps } = props;

return createComponentVNode(VNodeFlags.ComponentClass, Route, {
return createComponentVNode<any>(VNodeFlags.ComponentClass, Route, {
render(routeComponentProps) {
return createComponentVNode(
VNodeFlags.ComponentUnknown,
Expand Down
74 changes: 54 additions & 20 deletions packages/inferno/src/core/component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { VNodeFlags } from 'inferno-vnode-flags';
import { Props, VNode } from './implementation';
import { Props, VNode, InfernoChildren } from './implementation';
import { combineFrom, isFunction, isNull, isNullOrUndef, throwError } from 'inferno-shared';
import { updateClassComponent } from '../DOM/patching';
import { callAll, EMPTY_OBJ, LIFECYCLE } from '../DOM/utils/common';
Expand Down Expand Up @@ -109,6 +109,25 @@ function applyState<P, S>(component: Component<P, S>, force: boolean, callback?:
}
}

export interface ComponentLifecycle<P, S> {
componentDidMount?(): void;

componentWillMount?(): void;

componentWillReceiveProps?(nextProps: P, nextContext: any): void;

shouldComponentUpdate?(nextProps: P, nextState: S, nextContext: any): boolean;

componentWillUpdate?(nextProps: P, nextState: S, nextContext: any): void;

componentDidUpdate?(prevProps: P, prevState: S, prevContext: any): void;

componentWillUnmount?(): void;

getChildContext?(): void;
}

export interface Component<P = {}, S = {}> extends ComponentLifecycle<P, S> {}
export class Component<P, S> {
// Public
public static defaultProps: {} | null = null;
Expand All @@ -128,31 +147,14 @@ export class Component<P, S> {
public $UPD: boolean = true; // UPDATING
public $QU: Function[] | null = null; // QUEUE

constructor(props?: P, context?: any) {
constructor(props: P, context?: any) {
/** @type {object} */
this.props = props || (EMPTY_OBJ as P);

/** @type {object} */
this.context = context || EMPTY_OBJ; // context should not be mutable
}

// LifeCycle methods
public componentDidMount?(): void;

public componentWillMount?(): void;

public componentWillReceiveProps?(nextProps: P, nextContext: any): void;

public shouldComponentUpdate?(nextProps: P, nextState: S, nextContext: any): boolean;

public componentWillUpdate?(nextProps: P, nextState: S, nextContext: any): void;

public componentDidUpdate?(prevProps: P, prevState: S, prevContext: any): void;

public componentWillUnmount?(): void;

public getChildContext?(): void;

public forceUpdate(callback?: Function) {
if (this.$UN) {
return;
Expand All @@ -177,5 +179,37 @@ export class Component<P, S> {
}

// tslint:disable-next-line:no-empty
public render(nextProps?: P, nextState?, nextContext?): any {}
public render(nextProps?: P, nextState?, nextContext?): InfernoChildren {
return undefined;
}
}

export type SFC<P = {}> = StatelessComponent<P>;

export interface StatelessComponent<P = {}> {
(props: P & { children?: InfernoChildren }, context?: any): VNode<P> | null;

propTypes?: ValidationMap<P>;
contextTypes?: ValidationMap<any>;
defaultProps?: Partial<P>;
displayName?: string;
}

export interface ComponentClass<P = {}> {
new (props?: P, context?: any): Component<P, {}>;

propTypes?: ValidationMap<P>;
contextTypes?: ValidationMap<any>;
childContextTypes?: ValidationMap<any>;
defaultProps?: Partial<P>;
displayName?: string;
}

export type Validator<T> = { bivarianceHack(object: T, key: string, componentName: string, ...rest: any[]): Error | null }["bivarianceHack"];

export interface Requireable<T> extends Validator<T> {
isRequired: Validator<T>;
}

export type ValidationMap<T> = {[K in keyof T]?: Validator<T> };

32 changes: 16 additions & 16 deletions packages/inferno/src/core/implementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { validateVNodeElementChildren } from './validate';

const keyPrefix = '$';

export interface VNode {
export interface VNode<P = {}> {
children: InfernoChildren;
childFlags: ChildFlags;
dom: Element | null;
Expand All @@ -25,28 +25,28 @@ export interface VNode {
isValidated?: boolean;
key: null | number | string;
parentVNode: VNode | null;
props: Props | null;
ref: Ref | Refs | null;
props: Props & P | null;
ref: Ref | Refs<P> | null;
type: any;
}
export type InfernoInput = VNode | null | string | number;
export type Ref = (node?: Element | null) => any;
export type Ref<T = Element> = (node?: T | null) => any;
export type InfernoChildren = string | number | boolean | undefined | VNode | Array<string | number | VNode> | null;

export interface Props {
children?: InfernoChildren;
ref?: Ref | null;
key?: any;
className?: string;
[k: string]: any;
// [k: string]: any;
}

export interface Refs {
export interface Refs<P> {
onComponentDidMount?: (domNode: Element) => void;
onComponentWillMount?(): void;
onComponentShouldUpdate?(lastProps, nextProps): boolean;
onComponentWillUpdate?(lastProps, nextProps): void;
onComponentDidUpdate?(lastProps, nextProps): void;
onComponentShouldUpdate?(lastProps: P, nextProps: P): boolean;
onComponentWillUpdate?(lastProps: P, nextProps: P): void;
onComponentDidUpdate?(lastProps: P, nextProps: P): void;
onComponentWillUnmount?(domNode: Element): void;
}

Expand Down Expand Up @@ -81,15 +81,15 @@ function getVNode(childFlags: ChildFlags, children, className: string | null | u
};
}

export function createVNode(
export function createVNode<P>(
flags: VNodeFlags,
type,
className?: string | null,
children?: InfernoChildren,
childFlags?: ChildFlags,
props?: Props | null,
props?: Props & P | null,
key?: string | number | null,
ref?: Ref | Refs | null
ref?: Ref | Refs<P> | null
): VNode {
if (process.env.NODE_ENV !== 'production') {
if (flags & VNodeFlags.Component) {
Expand All @@ -116,7 +116,7 @@ export function createVNode(
return vNode;
}

export function createComponentVNode(flags: VNodeFlags, type, props?: Props | null, key?: null | string | number, ref?: Ref | Refs | null) {
export function createComponentVNode<P>(flags: VNodeFlags, type, props?: Props & P | null, key?: null | string | number, ref?: Ref | Refs<P> | null) {
if (process.env.NODE_ENV !== 'production') {
if (flags & VNodeFlags.HtmlElement) {
throwError('Creating element vNodes using createComponentVNode is not allowed. Use Inferno.createVNode method.');
Expand All @@ -132,11 +132,11 @@ export function createComponentVNode(flags: VNodeFlags, type, props?: Props | nu

if (!isNullOrUndef(defaultProps)) {
if (!props) {
props = {}; // Props can be referenced and modified at application level so always create new object
(props as any) = {}; // Props can be referenced and modified at application level so always create new object
}
for (const prop in defaultProps) {
if (isUndefined(props[prop])) {
props[prop] = defaultProps[prop];
if (isUndefined(props![prop])) {
props![prop] = defaultProps[prop];
}
}
}
Expand Down
Loading

0 comments on commit 124d1cd

Please sign in to comment.