Skip to content

Commit

Permalink
refactor: Removes typescript StateResolver limitations (#787)
Browse files Browse the repository at this point in the history
* `computed` and `effectOn` now allows unlimited state resolvers.

Co-authored-by: Jørn Myrland <[email protected]>
  • Loading branch information
no-stack-dub-sack and jmyrland authored Nov 13, 2022
1 parent 6e08efb commit eba7fc1
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 133 deletions.
143 changes: 10 additions & 133 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,37 +83,7 @@ type StateResolver<

type StateResolvers<Model extends object, StoreModel extends object> =
| []
| [StateResolver<Model, StoreModel, any>]
| [
StateResolver<Model, StoreModel, any>,
StateResolver<Model, StoreModel, any>,
]
| [
StateResolver<Model, StoreModel, any>,
StateResolver<Model, StoreModel, any>,
StateResolver<Model, StoreModel, any>,
]
| [
StateResolver<Model, StoreModel, any>,
StateResolver<Model, StoreModel, any>,
StateResolver<Model, StoreModel, any>,
StateResolver<Model, StoreModel, any>,
]
| [
StateResolver<Model, StoreModel, any>,
StateResolver<Model, StoreModel, any>,
StateResolver<Model, StoreModel, any>,
StateResolver<Model, StoreModel, any>,
StateResolver<Model, StoreModel, any>,
]
| [
StateResolver<Model, StoreModel, any>,
StateResolver<Model, StoreModel, any>,
StateResolver<Model, StoreModel, any>,
StateResolver<Model, StoreModel, any>,
StateResolver<Model, StoreModel, any>,
StateResolver<Model, StoreModel, any>,
];
| Array<StateResolver<Model, StoreModel, any>>;

type AnyFunction = (...args: any[]) => any;

Expand Down Expand Up @@ -696,6 +666,12 @@ type DefaultComputationFunc<Model extends object, Result> = (
state: State<Model>,
) => Result;

type ExtractReturnTypes<T extends readonly ((...args: any[]) => any)[]> = [
...{
[K in keyof T]: T[K] extends (...args: any[]) => infer R ? R : never;
},
];

export function computed<
Model extends object = {},
Result = void,
Expand All @@ -706,54 +682,7 @@ export function computed<
>,
>(
resolversOrCompFunc: Resolvers | DefaultComputationFunc<Model, Result>,
compFunc?: Resolvers extends [AnyFunction]
? (arg0: ReturnType<Resolvers[0]>) => Result
: Resolvers extends [AnyFunction, AnyFunction]
? (arg0: ReturnType<Resolvers[0]>, arg1: ReturnType<Resolvers[1]>) => Result
: Resolvers extends [AnyFunction, AnyFunction, AnyFunction]
? (
arg0: ReturnType<Resolvers[0]>,
arg1: ReturnType<Resolvers[1]>,
arg2: ReturnType<Resolvers[2]>,
) => Result
: Resolvers extends [AnyFunction, AnyFunction, AnyFunction, AnyFunction]
? (
arg0: ReturnType<Resolvers[0]>,
arg1: ReturnType<Resolvers[1]>,
arg2: ReturnType<Resolvers[2]>,
arg3: ReturnType<Resolvers[3]>,
) => Result
: Resolvers extends [
AnyFunction,
AnyFunction,
AnyFunction,
AnyFunction,
AnyFunction,
]
? (
arg0: ReturnType<Resolvers[0]>,
arg1: ReturnType<Resolvers[1]>,
arg2: ReturnType<Resolvers[2]>,
arg3: ReturnType<Resolvers[3]>,
arg4: ReturnType<Resolvers[4]>,
) => Result
: Resolvers extends [
AnyFunction,
AnyFunction,
AnyFunction,
AnyFunction,
AnyFunction,
AnyFunction,
]
? (
arg0: ReturnType<Resolvers[0]>,
arg1: ReturnType<Resolvers[1]>,
arg2: ReturnType<Resolvers[2]>,
arg3: ReturnType<Resolvers[3]>,
arg4: ReturnType<Resolvers[4]>,
arg5: ReturnType<Resolvers[5]>,
) => Result
: () => Result,
compFunc?: (...args: ExtractReturnTypes<Resolvers>) => Result,
): Computed<Model, Result, StoreModel>;

// #endregion
Expand All @@ -768,61 +697,9 @@ export type Unstable_EffectOn<
type: 'effectOn';
};

type DependencyResolver<State> = (state: State) => any;

type Dependencies<Resolvers extends StateResolvers<any, any>> =
Resolvers extends [AnyFunction]
? [ReturnType<Resolvers[0]>]
: Resolvers extends [AnyFunction, AnyFunction]
? [ReturnType<Resolvers[0]>, ReturnType<Resolvers[1]>]
: Resolvers extends [AnyFunction, AnyFunction, AnyFunction]
? [
ReturnType<Resolvers[0]>,
ReturnType<Resolvers[1]>,
ReturnType<Resolvers[2]>,
]
: Resolvers extends [AnyFunction, AnyFunction, AnyFunction, AnyFunction]
? [
ReturnType<Resolvers[0]>,
ReturnType<Resolvers[1]>,
ReturnType<Resolvers[2]>,
ReturnType<Resolvers[3]>,
]
: Resolvers extends [
AnyFunction,
AnyFunction,
AnyFunction,
AnyFunction,
AnyFunction,
]
? [
ReturnType<Resolvers[0]>,
ReturnType<Resolvers[1]>,
ReturnType<Resolvers[2]>,
ReturnType<Resolvers[3]>,
ReturnType<Resolvers[4]>,
]
: Resolvers extends [
AnyFunction,
AnyFunction,
AnyFunction,
AnyFunction,
AnyFunction,
AnyFunction,
]
? [
ReturnType<Resolvers[0]>,
ReturnType<Resolvers[1]>,
ReturnType<Resolvers[2]>,
ReturnType<Resolvers[3]>,
ReturnType<Resolvers[4]>,
ReturnType<Resolvers[4]>,
]
: any[];

type Change<Resolvers extends StateResolvers<any, any>> = {
prev: Dependencies<Resolvers>;
current: Dependencies<Resolvers>;
prev: ExtractReturnTypes<Resolvers>;
current: ExtractReturnTypes<Resolvers>;
action: {
type: string;
payload?: any;
Expand Down
195 changes: 195 additions & 0 deletions tests/typescript/state-resolvers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import {
action,
Action,
computed,
Computed,
unstable_effectOn,
Unstable_EffectOn,
} from 'easy-peasy';

type OneThroughFifteen = {
one: number;
two: number;
three: number;
four: number;
five: number;
six: number;
seven: number;
eight: number;
nine: number;
ten: number;
eleven: number;
twelve: number;
thirteen: number;
fourteen: number;
fifteen: number;
};

type SixteenThroughThirty = {
sixteen: number;
seventeen: number;
eighteen: number;
nineteen: number;
twenty: number;
twentyOne: number;
twentyTwo: number;
twentyThree: number;
twentyFour: number;
twentyFive: number;
twentySix: number;
twentySeven: number;
twentyEight: number;
twentyNine: number;
thirty: number;
};

type ActionPayload<T extends string> = {
key: T;
payload: number;
};

type NestedModel = SixteenThroughThirty & {
setState: Action<NestedModel, ActionPayload<keyof SixteenThroughThirty>>;
addAllTheThings: Computed<NestedModel, number, StoreModel>;
onStateChange: Unstable_EffectOn<NestedModel, StoreModel>;
};

type StoreModel = OneThroughFifteen & {
setState: Action<StoreModel, ActionPayload<keyof OneThroughFifteen>>;
addAllTheThings: Computed<StoreModel, number>;
onStateChange: Unstable_EffectOn<StoreModel>;
nestedModel: NestedModel;
};

const storeModel: StoreModel = {
one: 1,
two: 2,
three: 3,
four: 4,
five: 5,
six: 6,
seven: 7,
eight: 8,
nine: 9,
ten: 10,
eleven: 11,
twelve: 12,
thirteen: 13,
fourteen: 14,
fifteen: 15,
setState: action((state, { key, payload }) => {
state[key] = payload;
}),
addAllTheThings: computed(
[
(state) => state.one,
(state) => state.two,
(state) => state.three,
(state) => state.four,
(state) => state.five,
(state) => state.six,
(state) => state.seven,
(state) => state.eight,
(state) => state.nine,
(state) => state.ten,
(state) => state.eleven,
(state) => state.twelve,
(state) => state.thirteen,
(state) => state.fourteen,
(state) => state.fifteen,
],
(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) => {
return a + b + c + d + e + f + g + h + i + j + k + l + m + n + o;
},
),
onStateChange: unstable_effectOn(
[
(state) => state.one,
(state) => state.two,
(state) => state.three,
(state) => state.four,
(state) => state.five,
(state) => state.six,
(state) => state.seven,
(state) => state.eight,
(state) => state.nine,
(state) => state.ten,
(state) => state.eleven,
(state) => state.twelve,
(state) => state.thirteen,
(state) => state.fourteen,
(state) => state.fifteen,
],
(_, change) => {
const [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o] = change.current;
const [p, q, r, s, t, u, v, w, x, y, z, aa, bb, cc, dd] = change.prev;
// do something
},
),
nestedModel: {
sixteen: 16,
seventeen: 17,
eighteen: 18,
nineteen: 19,
twenty: 20,
twentyOne: 21,
twentyTwo: 22,
twentyThree: 23,
twentyFour: 24,
twentyFive: 25,
twentySix: 26,
twentySeven: 27,
twentyEight: 28,
twentyNine: 29,
thirty: 30,
setState: action((state, { key, payload }) => {
state[key] = payload;
}),
addAllTheThings: computed(
[
(state) => state.sixteen,
(state) => state.seventeen,
(state) => state.eighteen,
(state) => state.nineteen,
(state) => state.twenty,
(state) => state.twentyOne,
(state) => state.twentyTwo,
(state) => state.twentyThree,
(state) => state.twentyFour,
(state) => state.twentyFive,
(state) => state.twentySix,
(state) => state.twentySeven,
(state) => state.twentyEight,
(state) => state.twentyNine + state.thirty,
(_, storeState) => storeState.addAllTheThings,
],
(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) => {
return a + b + c + d + e + f + g + h + i + j + k + l + m + n + o;
},
),
onStateChange: unstable_effectOn(
[
(state) => state.sixteen,
(state) => state.seventeen,
(state) => state.eighteen,
(state) => state.nineteen,
(state) => state.twenty,
(state) => state.twentyOne,
(state) => state.twentyTwo,
(state) => state.twentyThree,
(state) => state.twentyFour,
(state) => state.twentyFive,
(state) => state.twentySix,
(state) => state.twentySeven,
(state) => state.twentyEight,
(state) => state.twentyNine,
(_, storeState) => storeState.addAllTheThings,
],
(_, change) => {
const [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o] = change.current;
const [p, q, r, s, t, u, v, w, x, y, z, aa, bb, cc, dd] = change.prev;
// do something
},
),
},
};

1 comment on commit eba7fc1

@vercel
Copy link

@vercel vercel bot commented on eba7fc1 Nov 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

easy-peasy – ./

easy-peasy-git-master-ctrlplusb.vercel.app
easy-peasy.dev
easy-peasy-ctrlplusb.vercel.app

Please sign in to comment.