Skip to content

Commit

Permalink
chore(react-kit): make withRX curried for better type inference micro…
Browse files Browse the repository at this point in the history
  • Loading branch information
raveclassic committed Oct 17, 2018
1 parent ff65323 commit 2380110
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 17 deletions.
26 changes: 13 additions & 13 deletions packages/react-kit/src/utils/__tests__/with-rx2.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ describe('withRX2', () => {
result$.next(props.foo);
return <div>{props.foo}</div>;
};
const FooContainer = withRX(
Foo,
const FooContainer = withRX(Foo)(
() => ({
props: {
foo: foo$,
Expand All @@ -51,24 +50,23 @@ describe('withRX2', () => {
}
}
const handler = jest.fn();
const FooContainer = withRX(Foo, () => ({ defaultProps: { handler } }));
const FooContainer = withRX(Foo)(() => ({ defaultProps: { handler } }));
const foo = mount(<FooContainer foo={'test'} />);
foo.find('#id').simulate('click');
expect(handler).toHaveBeenCalledWith('test');
foo.unmount();
});
it('should pass defaultValues', () => {
const Foo: SFC<FooProps> = props => <div id={'foo'}>{props.foo}</div>;
const FooContainer = withRX(Foo, () => ({ defaultProps: { foo: 'default' } }));
const FooContainer = withRX(Foo)(() => ({ defaultProps: { foo: 'default' } }));
const foo = mount(<FooContainer />);
expect(foo.find('#foo').text()).toBe('default');
foo.unmount();
});
it('should immediately unsubscribe on unmount', () => {
const Foo: SFC<FooProps> = props => <div id={'foo'}>{props.foo}</div>;
const foo$ = scheduler.createHotObservable<string>('^-a-b-|');
const FooContainer = withRX(
Foo,
const FooContainer = withRX(Foo)(
props$ => ({
props: {
foo: foo$,
Expand All @@ -87,8 +85,7 @@ describe('withRX2', () => {
res: '-a-b-|',
};
const effects$ = scheduler.createColdObservable(timeline.src);
const FooContainer = withRX(
Foo,
const FooContainer = withRX(Foo)(
() => ({
effects$,
}),
Expand All @@ -103,7 +100,7 @@ describe('withRX2', () => {
it('should immediately unsubscribe from effects on unmount', () => {
const Foo = () => <div />;
const effects$ = scheduler.createColdObservable('-a-b-|');
const FooContainer = withRX(Foo, () => ({ effects$ }), { scheduler });
const FooContainer = withRX(Foo)(() => ({ effects$ }), { scheduler });
const foo = mount(<FooContainer />);
foo.unmount();
scheduler.expectSubscriptions(effects$.subscriptions).toBe('(^!)');
Expand All @@ -115,16 +112,19 @@ describe('withRX2', () => {
handler: (arg: number) => void;
};
const Foo: SFC<Props> = () => <div>hi</div>;
const C = withRX(Foo, () => ({}), { scheduler });
const C1 = withRX(Foo, () => ({ defaultProps: { handler: constUndefined } }), { scheduler });
const C2 = withRX(Foo, () => ({ defaultProps: { foo: '123', adsfsd: 123 } }), { scheduler });
const C3 = withRX(Foo, () => ({ defaultProps: { foo: '123', bar: 213 } }), { scheduler });
const C = withRX(Foo)(() => ({}), { scheduler });
const C1 = withRX(Foo)(() => ({ defaultProps: { handler: constUndefined } }), { scheduler });
const C2 = withRX(Foo)(() => ({ defaultProps: { foo: '123', adsfsd: 123 } }), { scheduler });
const C3 = withRX(Foo)(() => ({ defaultProps: { foo: '123', bar: 213 } }), { scheduler });
//argument inference is working
const C4 = withRX(Foo)(() => ({ defaultProps: { handler(arg) {} } }), { scheduler });
(() => [
<C handler={constUndefined} foo={'123'} bar={123} />,
<C1 foo={'123'} bar={123} />,
<C1 foo={'123'} bar={123} handler={constUndefined} />,
<C2 handler={constUndefined} bar={123} />,
<C3 handler={constUndefined} />,
<C4 foo={'123'} bar={123} />,
])();
});
});
11 changes: 7 additions & 4 deletions packages/react-kit/src/utils/with-rx2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ export type WithRXOptions = {
scheduler?: SchedulerLike;
};

export function withRX<P extends object, D extends Partial<P>>(
Target: ComponentType<P>,
/**
* curried for better type inference
* @see https://github.com/Microsoft/TypeScript/issues/15005#issuecomment-430588884
*/
export const withRX = <P extends object>(Target: ComponentType<P>) => <D extends Partial<P>>(
selector: (props$: Observable<Readonly<P>>) => WithRXSelectorResult<P, D>,
options: WithRXOptions = {},
): ComponentClass<Omit<P, keyof D> & Partial<D>> {
): ComponentClass<Omit<P, keyof D> & Partial<D>> => {
const scheduler = options.scheduler || animationFrame;

class WithRX extends PureComponent<P, Partial<P>> {
Expand Down Expand Up @@ -66,4 +69,4 @@ export function withRX<P extends object, D extends Partial<P>>(
hoistNonReactStatics(WithRX, Target);

return WithRX as any; //defaultProps are tracked by defaultProps argument;
}
};

0 comments on commit 2380110

Please sign in to comment.