diff --git a/index.d.ts b/index.d.ts index 6dd2cc302..b35667ae4 100644 --- a/index.d.ts +++ b/index.d.ts @@ -98,8 +98,9 @@ type FilterStateTypes = Overwrite< * type OnlyActions = Actions; */ export type Actions = { - [P in keyof FilterActionTypes< - Pick> + [P in keyof Overwrite< + FilterActionTypes>>, + Pick> >]: Model[P] extends Thunk ? Param1 extends void ? () => R extends Promise ? R : Promise @@ -108,7 +109,9 @@ export type Actions = { ? Param1 extends void ? () => void : (payload: Param1) => void - : Actions; + : Model[P] extends object + ? Actions + : unknown; }; type RequiredOnly = Pick>; @@ -136,11 +139,11 @@ type RecursiveState< RequiredModel extends Object, OptionalModel extends Object > = Overwrite< - { [P in keyof OtherModel]: OtherModel[P] }, Overwrite< { [P in keyof RequiredModel]: StateModelValues }, { [P in keyof OptionalModel]?: StateModelValues } - > + >, + { [P in keyof OtherModel]: OtherModel[P] } >; type FilterIndexSignatures< diff --git a/src/__tests__/typescript/issue224.ts b/src/__tests__/typescript/issue224.ts new file mode 100644 index 000000000..5637868a1 --- /dev/null +++ b/src/__tests__/typescript/issue224.ts @@ -0,0 +1,81 @@ +/* eslint-disable */ + +import { + createStore, + computed, + Computed, + action, + Action, + thunk, + Thunk, +} from 'easy-peasy'; + +interface ObjectWithId { + id: number; +} + +interface Nested { + save: Thunk; +} + +interface DataModel { + data: { [key: number]: DataItem }; + sortBy: keyof DataItem | 'none'; + ids: Computed, string[]>; + fetched: Action, DataItem[]>; + fetch: Thunk, string>; + getItemById: Computed< + DataModel, + (id: number) => DataItem | undefined + >; + nested: Nested; +} + +const dataModel = ( + endpoint: () => Promise, +): DataModel => { + const result: DataModel = { + data: {}, + ids: computed(state => Object.keys(state.data)), + fetched: action((state, items) => { + items.forEach((item, idx) => { + state.data[idx] = item; + }); + 84656; + }), + fetch: thunk(async (actions, payload) => { + const data = await endpoint(); + actions.fetched(data); + // Nested actions do not work on generics :( + // typings:expect-error + actions.nested.save(); + }), + getItemById: computed(state => (id: number) => + Object.values(state.data).find(item => item.id === id), + ), + sortBy: 'id', + nested: { + save: thunk(() => {}), + }, + }; + return result; +}; + +interface Person extends ObjectWithId { + id: number; + name: string; +} + +const personModel = dataModel(() => + Promise.resolve([{ id: 1, name: 'bob' }]), +); + +const store = createStore(personModel); + +store.getState().sortBy; + +store.getActions().fetched([]); +store.getActions().data; +// typings:expect-error +store.getActions().sortBy; +store.getActions().nested.save();