Skip to content

Commit 08afccf

Browse files
feat(overmind): improve typing of payload to transition
1 parent 6c9e154 commit 08afccf

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

packages/node_modules/overmind/src/statemachine.test.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,15 @@ describe('Statemachine', () => {
99

1010
type States = {
1111
state: 'FOO'
12-
string: string
1312
} | {
1413
state: 'BAR'
15-
number: number
1614
}
1715

1816
const state = statemachine<States>({
1917
FOO: ['BAR'],
2018
BAR: ['FOO']
2119
}, {
2220
state: 'FOO',
23-
string: 'hey'
2421
})
2522

2623
const config = {

packages/node_modules/overmind/src/statemachine.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,25 @@ type TStates = {
77
state: string | number,
88
}
99

10+
export type Exact<Expected, Actual> =
11+
keyof Expected extends keyof Actual
12+
? keyof Actual extends keyof Expected
13+
? Expected extends ExactElements<Expected, Actual>
14+
? Expected
15+
: never
16+
: never
17+
: never;
18+
19+
type ExactElements<Expected, Actual> = {
20+
[K in keyof Actual]: K extends keyof Expected
21+
? Expected[K] extends Actual[K]
22+
? Actual[K] extends Expected[K]
23+
? Expected[K]
24+
: never
25+
: never
26+
: never
27+
};
28+
1029
export type StatemachineTransitions<States extends TStates> = {
1130
[State in States["state"]]: Array<States["state"]>
1231
}
@@ -19,7 +38,7 @@ export interface MachineMethods<States extends TStates, Base extends IState = {}
1938
state: T,
2039
newState: States extends {
2140
state: T
22-
} ? Omit<States, 'state'> : never,
41+
} ? Exact<Omit<States, 'state'>, {}> extends never ? Omit<States, 'state'> & Partial<Base> : Exact<Partial<Base>, {}> extends never ? Partial<Base> : { [NO_PROP]?: true} : never,
2342
callback?: ((current: Statemachine<Base, States, States extends {
2443
state: T
2544
} ? States : never>) => O)
@@ -32,6 +51,8 @@ const INITIAL_STATE = Symbol('INITIAL_STATE')
3251
const TRANSITIONS = Symbol('TRANSITIONS')
3352
const BASE = Symbol('BASE')
3453
const STATE = Symbol('STATE')
54+
const CURRENT_KEYS = Symbol('CURRENT_KEYS')
55+
const NO_PROP = Symbol('NO_PROP')
3556

3657
export class StateMachine<Base extends IState, States extends TStates, State extends TStates = States, > {
3758
state: State["state"]
@@ -46,6 +67,7 @@ export class StateMachine<Base extends IState, States extends TStates, State ext
4667
this[INITIAL_STATE] = state.state
4768
this[TRANSITIONS] = transitions
4869
this[BASE] = base || {}
70+
this[CURRENT_KEYS] = Object.keys(state)
4971
Object.assign(this, state, base)
5072
}
5173
matches(...states) {
@@ -70,17 +92,15 @@ export class StateMachine<Base extends IState, States extends TStates, State ext
7092
if (transitions[this.state].includes(state)) {
7193
const tree = (this[PROXY_TREE].master.mutationTree || this[PROXY_TREE])
7294
const base = this[VALUE][BASE]
73-
const baseKeys = Object.keys(base || {}).concat('state')
7495

7596
tree.enableMutations()
76-
Object.keys(this).forEach((key) => {
77-
if (!baseKeys.includes(key)) {
78-
delete this[key]
79-
}
97+
this[VALUE][CURRENT_KEYS].forEach((key) => {
98+
delete this[key]
8099
})
81100

82101
Object.assign(this, newState)
83102
this.state = state
103+
this[VALUE][CURRENT_KEYS] = Object.keys(newState)
84104

85105
let result
86106
if (callback) {

0 commit comments

Comments
 (0)