Skip to content

Commit

Permalink
Massive refactor to typescript typings, adds support for defaultprops
Browse files Browse the repository at this point in the history
and many typing fixes. Fixes Github#1536
  • Loading branch information
Havunen committed Feb 20, 2022
1 parent 66ea4bd commit 696006c
Show file tree
Hide file tree
Showing 34 changed files with 1,715 additions and 2,989 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@
"version": "npm run build && npm run docs-build && git add docs && npm run test",
"prettier": "npm-run-all prettier:*",
"prettier:tests-js": "prettier --print-width 160 --trailing-comma none --single-quote true --write --list-different packages/*/__tests__/**/*.{js,jsx}",
"prettier:tests-ts": "prettier --print-width 160 --trailing-comma none --single-quote true --write --list-different --parser=typescript packages/*/__tests__/**/*.{ts,tsx}",
"prettier:src": "prettier --print-width 160 --trailing-comma none --single-quote true --write --list-different --parser=typescript packages/*/src/**/*.{ts,tsx}",
"prettier:fixtures": "prettier --print-width 160 --trailing-comma none --single-quote true --write --list-different fixtures/**/*.{js,jsx}",
"prettier:scripts": "prettier --print-width 160 --trailing-comma none --single-quote true --write --list-different scripts/**/*.{js,jsx}",
"prettier:tests-ts": "prettier --print-width 160 --trailing-comma none --single-quote true --write --list-different --parser=typescript packages/*/__tests__/**/*.tsx",
"prettier:src": "prettier --print-width 160 --trailing-comma none --single-quote true --write --list-different --parser=typescript packages/*/src/**/*.ts",
"prettier:fixtures": "prettier --print-width 160 --trailing-comma none --single-quote true --write --list-different fixtures/**/*.js",
"prettier:scripts": "prettier --print-width 160 --trailing-comma none --single-quote true --write --list-different scripts/**/*.js",
"postinstall": "lerna bootstrap --no-ci && run-p install:* && npm run build",
"test": "npm run test:node && npm run test:node-nodom && npm run test:browser",
"test:node": "cross-env NODE_ENV=test jest --config --no-watchman",
Expand Down
4 changes: 2 additions & 2 deletions packages/inferno-animation/src/AnimatedAllComponent.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Component, InfernoNode } from 'inferno';
import { Component, Inferno } from "inferno";
import { componentDidAppear, componentWillDisappear, componentWillMove, AnimationClass } from './animations';

type AnimationProp = {
animation?: string | AnimationClass;
children?: InfernoNode;
children?: Inferno.InfernoNode;
};

export class AnimatedAllComponent<P = {}, S = {}> extends Component<AnimationProp & P, S> {
Expand Down
4 changes: 2 additions & 2 deletions packages/inferno-animation/src/AnimatedComponent.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Component, InfernoNode } from 'inferno';
import { Component, Inferno } from 'inferno';
import { componentDidAppear, componentWillDisappear, AnimationClass } from './animations';

type AnimationProp = {
animation?: string | AnimationClass;
children?: InfernoNode;
children?: Inferno.InfernoNode;
};

export class AnimatedComponent<P = {}, S = {}> extends Component<AnimationProp & P, S> {
Expand Down
4 changes: 2 additions & 2 deletions packages/inferno-animation/src/AnimatedMoveComponent.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Component, InfernoNode } from 'inferno';
import { Component, Inferno } from 'inferno';
import { componentWillMove, AnimationClass } from './animations';

type AnimationProp = {
animation?: string | AnimationClass;
children?: InfernoNode;
children?: Inferno.InfernoNode;
};

export class AnimatedMoveComponent<P = {}, S = {}> extends Component<AnimationProp & P, S> {
Expand Down
11 changes: 5 additions & 6 deletions packages/inferno-compat/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@ import {
forwardRef,
Fragment,
getFlagsForElementVnode,
InfernoNode,
Inferno,
linkEvent,
normalizeProps,
options,
Props,
rerender,
VNode
} from 'inferno';
export type { ComponentType, InfernoNode, Props, Refs, VNode } from 'inferno';
export type { ComponentType, Inferno, Refs, VNode } from 'inferno';
import { hydrate } from 'inferno-hydrate';
import { cloneVNode } from 'inferno-clone-vnode';
import { createClass } from 'inferno-create-class';
Expand All @@ -57,7 +56,7 @@ function unmountComponentAtNode(container: Element | SVGAElement | DocumentFragm
return true;
}

export type IterateChildrenFn = (value: InfernoNode | any, index: number, array: any[]) => any;
export type IterateChildrenFn = (value: Inferno.InfernoNode | any, index: number, array: any[]) => any;

function flatten(arr, result) {
for (let i = 0, len = arr.length; i < len; ++i) {
Expand Down Expand Up @@ -102,7 +101,7 @@ const Children = {
children = Children.toArray(children);
return children.length;
},
only(children: any[]): InfernoNode | any {
only(children: any[]): Inferno.InfernoNode | any {
children = Children.toArray(children);
if (children.length !== 1) {
throw new Error('Children.only() expects only one child.');
Expand Down Expand Up @@ -170,7 +169,7 @@ function normalizeGenericProps(props) {
}
}

function normalizeFormProps<P>(name: string, props: Props<P> | any) {
function normalizeFormProps(name: string, props: any) {
if ((name === 'input' || name === 'textarea') && props.type !== 'radio' && props.onChange) {
const type = props.type && props.type.toLowerCase();
let eventName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ describe('CreateElement (non-JSX)', () => {
});

it('Should check component props', () => {
class App extends Component<{ className: string }, any> {
type MyComponentProps = { className: string }

class App extends Component<MyComponentProps, any> {
public render() {
return createElement('div', { className: this.props.className }, createElement('div', { className: 'title' }, 'Example'), createElement('hr'));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('Github1176', () => {
it('Should not crash', (done) => {
const Loader = () => <div className="loader">Loader...</div>;

class Component1 extends Component {
class Component1 extends Component<any, any> {
public render() {
return (
<div className="component1">
Expand Down
18 changes: 8 additions & 10 deletions packages/inferno-create-element/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ import {
createComponentVNode,
createFragment,
createVNode,
getFlagsForElementVnode,
IComponentConstructor,
Key,
Props,
StatelessComponent,
getFlagsForElementVnode, IComponentConstructor, Inferno,
Key, Props,
VNode
} from 'inferno';
} from "inferno";
import { isInvalid, isNullOrUndef, isString, isUndefined } from 'inferno-shared';
import { ChildFlags, VNodeFlags } from 'inferno-vnode-flags';
import StatelessComponent = Inferno.StatelessComponent;

const componentHooks = {
onComponentDidAppear: 1,
Expand All @@ -30,8 +28,8 @@ const componentHooks = {
* @param {...{object}=} _children Optional children for virtual node
* @returns {VNode} new virtual node
*/
export function createElement<T>(type: string | IComponentConstructor<T> | StatelessComponent<T>, props?: (T & Props<T>) | null, ..._children: any[]): VNode;
export function createElement<T>(type: string | IComponentConstructor<T> | StatelessComponent<T>, props?: (T & Props<T>) | null, _children?: any): VNode {
export function createElement<P>(type: string | IComponentConstructor<P> | StatelessComponent<P>, props?: (P & Props<P>) | null, ..._children: any[]): VNode;
export function createElement<P>(type: string | IComponentConstructor<P> | StatelessComponent<P>, props?: (P & Props<P>) | null, _children?: any): VNode {
if (process.env.NODE_ENV !== 'production') {
if (isInvalid(type)) {
throw new Error(
Expand Down Expand Up @@ -83,13 +81,13 @@ export function createElement<T>(type: string | IComponentConstructor<T> | State
flags = VNodeFlags.ComponentUnknown;
if (!isUndefined(children)) {
if (!props) {
props = {} as T;
props = {} as P;
}
props.children = children;
}

if (!isNullOrUndef(props)) {
newProps = {} as T & Props<T>;
newProps = {} as P & Props<P>;

for (const prop in props) {
if (prop === 'key') {
Expand Down
14 changes: 11 additions & 3 deletions packages/inferno-hyperscript/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { createComponentVNode, createFragment, createVNode, Fragment, getFlagsForElementVnode, InfernoNode, VNode } from 'inferno';
import {
createComponentVNode,
createFragment,
createVNode,
Fragment,
getFlagsForElementVnode,
Inferno,
VNode
} from "inferno";
import { isArray, isString, isStringOrNumber, isUndefined } from 'inferno-shared';
import { ChildFlags, VNodeFlags } from 'inferno-vnode-flags';

Expand All @@ -9,7 +17,7 @@ function parseTag(tag: string | null, props: any): string {
if (!tag) {
return 'div';
}
if (tag === Fragment) {
if (tag === (Fragment as any)) {
return tag;
}
const noId = props && isUndefined(props.id);
Expand Down Expand Up @@ -60,7 +68,7 @@ function isChildren(x: any): boolean {
* @param {string|number|VNode|Array<string|number|VNode>|null=} _children Optional children for virtual node
* @returns {VNode} returns new virtual node
*/
export function h(_tag: string | VNode | Function, _props?: any, _children?: InfernoNode): VNode {
export function h(_tag: string | VNode | Function, _props?: any, _children?: Inferno.InfernoNode): VNode {
// If a child array or text node are passed as the second argument, shift them
if (!_children && isChildren(_props)) {
_children = _props;
Expand Down
40 changes: 32 additions & 8 deletions packages/inferno-mobx/__tests__/types.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, render, SFC } from 'inferno';
import { Component, render } from 'inferno';
import { Provider } from 'inferno-mobx';
import * as mobx from 'mobx';

Expand All @@ -19,24 +19,48 @@ describe('top level context', () => {
describe('Rendering types', () => {
it('Should render SFC', () => {
// SFC
const MyComponent: SFC = (props) => {
return <div>{props.children}</div>; // Error: Property 'children' does not exist on type 'Refs<{}>'.
const MyComponent = (props) => {
return <div>{props.children}</div>;
};

render(
<MyComponent />, // Error: JSX element type 'InfernoNode' is not a constructor function for JSX elements. Type 'string' is not assignable to type 'Element | null'
<MyComponent />,
container
);
});

it('Should be possible to return void from render SFC', () => {
it('Should be possible to return string from render SFC', () => {
// SFC
const MyComponent: SFC = () => {
return;
const MyComponent = () => {
return 'd';
};

render(
<MyComponent />, // Error: JSX element type 'InfernoNode' is not a constructor function for JSX elements. Type 'string' is not assignable to type 'Element | null'
<MyComponent />,
container
);
});

it('Should be possible to return number from render SFC', () => {
// SFC
const MyComponent = () => {
return 1;
};

render(
<MyComponent />,
container
);
});

it('Should be possible to return null from render SFC', () => {
// SFC
const MyComponent = () => {
return null;
};

render(
<MyComponent />,
container
);
});
Expand Down
8 changes: 3 additions & 5 deletions packages/inferno-mobx/src/observerPatch.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { InfernoNode } from 'inferno';
import { warning } from 'inferno-shared';
import { Reaction } from 'mobx';
import { Inferno } from "inferno";

type RenderReturn = InfernoNode | undefined | void;

type Render = (this, properties?, state?, context?) => RenderReturn;
type Render = (this, properties?, state?, context?) => Inferno.InfernoNode;

type ObserverRender<R extends Render = Render> = R & { dispose: () => void };

function makeObserverRender<R extends Render>(update: () => void, render: R, name: string): ObserverRender<R> {
const reactor = new Reaction(name, update);
const track = reactor.track.bind(reactor);
const observer = function (this, ...parameters: Parameters<typeof render>) {
let rendered: RenderReturn;
let rendered: Inferno.InfernoNode;
let caught;
track(() => {
try {
Expand Down
6 changes: 3 additions & 3 deletions packages/inferno-redux/src/components/Provider.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, InfernoNode } from 'inferno';
import { Component, Inferno } from 'inferno';
import { Action, AnyAction, Store } from 'redux';
import { warning } from '../utils/warning';

Expand All @@ -15,7 +15,7 @@ const warnAboutReceivingStore = () => {

export interface Props<A extends Action = AnyAction> {
store: Store<any, A>;
children?: InfernoNode;
children?: Inferno.InfernoNode;
}

export class Provider<A extends Action = AnyAction> extends Component<Props<A>, null> {
Expand All @@ -33,7 +33,7 @@ export class Provider<A extends Action = AnyAction> extends Component<Props<A>,

// Don't infer the return type. It may be expanded and cause reference errors
// in the output.
public render(): InfernoNode | undefined {
public render(): Inferno.InfernoNode | undefined {
return this.props.children;
}

Expand Down
4 changes: 2 additions & 2 deletions packages/inferno-router/src/HashRouter.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Component, createComponentVNode, InfernoNode, VNode } from 'inferno';
import { Component, createComponentVNode, Inferno, VNode } from "inferno";
import { VNodeFlags } from 'inferno-vnode-flags';
import { createHashHistory } from 'history';
import { Router } from './Router';
import { warning } from './utils';

export interface IHashRouterProps {
children: InfernoNode;
children: Inferno.InfernoNode;
}

export class HashRouter extends Component<IHashRouterProps, any> {
Expand Down
4 changes: 2 additions & 2 deletions packages/inferno-router/src/Link.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createVNode, InfernoMouseEvent, linkEvent, VNode } from 'inferno';
import { createVNode, Inferno, InfernoMouseEvent, linkEvent, VNode } from "inferno";
import { ChildFlags, VNodeFlags } from 'inferno-vnode-flags';
import { invariant } from './utils';
import { combineFrom, isString } from 'inferno-shared';
Expand Down Expand Up @@ -44,7 +44,7 @@ function handleClick({ props, context }, event: InfernoMouseEvent<any>) {
/**
* The public API for rendering a history-aware <a>.
*/
export function Link(props: ILinkProps & LinkHTMLAttributes<HTMLLinkElement>, context): VNode {
export function Link(props: ILinkProps & Inferno.LinkHTMLAttributes<HTMLLinkElement>, context): VNode {
const { replace, children, className, to = '', innerRef, ...rest } = props;
invariant(context.router, 'You should not use <Link> outside a <Router>');

Expand Down
2 changes: 1 addition & 1 deletion packages/inferno-router/src/MemoryRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface IMemoryRouterProps {
export class MemoryRouter extends Component<IMemoryRouterProps, any> {
public history;

constructor(props?: any, context?: any) {
constructor(props?: IMemoryRouterProps, context?: any) {
super(props, context);
this.history = createMemoryHistory(props);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/inferno-router/src/NavLink.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createComponentVNode, VNode } from 'inferno';
import { createComponentVNode, Inferno, VNode } from "inferno";
import { VNodeFlags } from 'inferno-vnode-flags';
import { Route } from './Route';
import { ILinkProps, Link } from './Link';
Expand Down Expand Up @@ -38,7 +38,7 @@ export function NavLink({
isActive: getIsActive,
ariaCurrent = 'true',
...rest
}: NavLinkProps & LinkHTMLAttributes<HTMLLinkElement>): any {
}: NavLinkProps & Inferno.LinkHTMLAttributes<HTMLLinkElement>): any {
function linkComponent({ location, match }): VNode {
const isActive = Boolean(getIsActive ? getIsActive(match, location) : match);

Expand Down
Loading

0 comments on commit 696006c

Please sign in to comment.