Skip to content

Commit

Permalink
feat(time): add type tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kireevmp committed Mar 8, 2023
1 parent 9ac1506 commit fe78c6b
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 3 deletions.
4 changes: 3 additions & 1 deletion src/time/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ import { createEffect, Effect, Event, forward, restore, Store } from 'effector';

const defaultNow = <Time = number>() => Date.now() as unknown as Time;

type NoInfer<T> = [T][T extends any ? 0 : never];

export function time<Time = number>({
clock,
getNow,
initial,
}: {
clock: Event<any> | Effect<any, any, any> | Store<any>;
getNow?: () => Time;
initial?: Time;
initial?: NoInfer<Time>;
}): Store<Time> {
const timeReader = getNow ?? defaultNow;
const readNowFx = createEffect<void, Time>(timeReader);
Expand Down
4 changes: 2 additions & 2 deletions src/time/time.fork.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ test('store must correctly serializes', async () => {
await allSettled(clock, { scope: scopeB });
expect(serialize(scopeA)).toMatchInlineSnapshot(`
{
"-9m03zk|-ys9vce": 2,
"-9m03zk|-xu6mk0": 2,
}
`);
expect(serialize(scopeB)).toMatchInlineSnapshot(`
{
"-9m03zk|-ys9vce": 3,
"-9m03zk|-xu6mk0": 3,
}
`);
});
75 changes: 75 additions & 0 deletions test-typings/time.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { expectType } from 'tsd';
import { Store, createStore, createEvent, createEffect, createDomain } from 'effector';
import { time } from '../src/time';

// Returns correct default Store value
{
const clock = createEvent<void>();

expectType<Store<number>>(time({ clock }));
expectType<Store<number>>(time({ clock, initial: 100 }));
}

// Infers correct Store value
{
const clock = createEvent<void>();

const getNowString = (): string => 'time';
const getNowNumber = (): number => 0;
const getNowDate = (): Date => new Date();

expectType<Store<string>>(time({ clock, getNow: getNowString }));
expectType<Store<number>>(time({ clock, getNow: getNowNumber }));
expectType<Store<Date>>(time({ clock, getNow: getNowDate }));

const getNowUnion = (): 'a' | 'b' | 0 => 'a';

expectType<Store<'a' | 'b' | 0>>(time({ clock, getNow: getNowUnion }));
}

// getNow and initial types should match
{
const clock = createEvent<void>();

const getNowString = (): string => 'time';
const getNowDate = (): Date => new Date();

expectType<Store<Date>>(time({ clock, getNow: getNowDate, initial: new Date() }));
expectType<Store<string>>(
time({ clock, getNow: getNowString, initial: 'another' }),
);

// @ts-expect-error
time({ clock, getNow: getNowString, initial: 100 });
// @ts-expect-error
time({ clock, getNow: getNowDate, initial: 100 });
}

// Does not infer Store value from initial
{
const clock = createEvent<void>();

// @ts-expect-error
time({ clock, initial: new Date() });
// @ts-expect-error
time({ clock, initial: 'time' });
}

// Clock only accepts valid units
{
const event = createEvent<void>();
const effectFx = createEffect<void, void, void>();
const $store = createStore<void>(undefined);

expectType<Store<number>>(time({ clock: event }));
expectType<Store<number>>(time({ clock: effectFx }));
expectType<Store<number>>(time({ clock: $store }));

const fn = () => null;
const domain = createDomain()

// @ts-expect-error
time({ clock: fn });
// @ts-expect-error
time({ clock: domain });
}

0 comments on commit fe78c6b

Please sign in to comment.