We were unable to load Disqus. If you are a moderator please see our troubleshooting guide.

Florian • 7 months ago

For me one of the biggest obstacles in functional event sourcing / using the decider pattern is how to handle states with properties that either depend on other state fields (state being a discriminated union) or where there is, from a domain perspective, a link between event and state fields. This often leads to domain invariants being sprinkled across command handlers / the decider function and the state reducer / evolve function.

You can see it in your reduced example as well, where you need checks in the evolve function like `if (state.status !== 'NotExisting') return state;` to enforce domain invariants.

This problem balloons if both state and event are discriminated unions. Let's say you add a guest category ("commercial" | "private"). Depending on the guest category there are different fields in both the state and the checkout events.

I haven't seen a good solution to this problem yet. Have you encountered this?

goq1234 • 1 year ago

Why you put this extend in type definition?
```
export type Command<
CommandType extends string = string,
CommandData extends Record<string, unknown> = Record<string, unknown>,
> = Readonly<{
type: Readonly<CommandType>;
data: Readonly<CommandData>;
}>;
```

especially for string what is difference between your version and :

```
export type Command<
CommandData extends Record<string, unknown> = Record<string, unknown>,
> = Readonly<{
type: Readonly<string>;
data: Readonly<CommandData>;
}>;
```

?