Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ I highly recommend to add a bounty to the issue that you're waiting for to incre
- [Redux](#redux)
- [Store Configuration](#store-configuration)
- [Create Global Store Types](#create-global-store-types)
- [Types Global Namespace](#types-global-namespace)
- [Create Store](#create-store)
- [Action Creators 🌟](#action-creators-)
- [Reducers](#reducers)
Expand Down Expand Up @@ -1311,6 +1312,32 @@ declare module 'typesafe-actions' {

```

### Types Global Namespace

The playground uses a project-wide ambient module named `MyTypes` as a single import point for cross-cutting application types. It is a type-only module: it does not create runtime code, and it is not a package that needs to exist in `node_modules`.

Each application area extends this module from the place that owns the type. The store owns `RootState`, `RootAction`, and `Store`, so those declarations live next to the store setup. The services layer owns the `Services` dependency container used by epics, so it adds that type from the services folder:

```tsx
declare module 'MyTypes' {
export type Services = typeof import('./index').default;
}

Comment on lines +1324 to +1325

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

There is an unnecessary blank line at the end of this code block. Removing it will keep the formatting consistent with other blocks in the guide.

Suggested change
}
}

```

The store declaration also augments `typesafe-actions` with the same `RootAction` through its `Types` interface. That lets helpers from `typesafe-actions` understand the app's root action union without each feature re-declaring it.

This keeps the dependency direction simple. Feature modules export their own action, state, selector, and service types. The root store or service barrel composes those exports into application-wide types, and consumers import only the stable names they need. This section uses named imports for root-level aliases; the guide's existing namespace-style examples remain useful when grouped access to the ambient module is clearer:

```tsx
import { RootAction, RootState, Services } from 'MyTypes';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This example introduces named imports from the MyTypes module (e.g., import { RootAction, ... }). However, existing examples throughout the guide (such as at lines 692 and 1803) use a default import style: import MyTypes from 'MyTypes'.

To maintain a consistent teaching pattern and avoid confusing readers, it would be beneficial to either update the existing examples to use named imports or explicitly mention that named imports are the preferred approach for this pattern.


// reducer(state: RootState, action: RootAction)
// Epic<RootAction, RootAction, RootState, Services>
```

The main benefit is that ownership stays local. When a feature is removed, its local exports and the corresponding root composition can be removed with it. Components, reducers, epics, and tests still get a consistent type vocabulary without every file needing to know where each root type is assembled.

[⇧ back to top](#table-of-contents)

### Create Store
Expand Down
22 changes: 22 additions & 0 deletions README_SOURCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ I highly recommend to add a bounty to the issue that you're waiting for to incre
- [Redux](#redux)
- [Store Configuration](#store-configuration)
- [Create Global Store Types](#create-global-store-types)
- [Types Global Namespace](#types-global-namespace)
- [Create Store](#create-store)
- [Action Creators 🌟](#action-creators-)
- [Reducers](#reducers)
Expand Down Expand Up @@ -516,6 +517,27 @@ Can be imported in various layers receiving or sending redux actions like: reduc

::codeblock='playground/src/store/types.d.ts'::

### Types Global Namespace

The playground uses a project-wide ambient module named `MyTypes` as a single import point for cross-cutting application types. It is a type-only module: it does not create runtime code, and it is not a package that needs to exist in `node_modules`.

Each application area extends this module from the place that owns the type. The store owns `RootState`, `RootAction`, and `Store`, so those declarations live next to the store setup. The services layer owns the `Services` dependency container used by epics, so it adds that type from the services folder:

::codeblock='playground/src/services/types.d.ts'::

The store declaration also augments `typesafe-actions` with the same `RootAction` through its `Types` interface. That lets helpers from `typesafe-actions` understand the app's root action union without each feature re-declaring it.

This keeps the dependency direction simple. Feature modules export their own action, state, selector, and service types. The root store or service barrel composes those exports into application-wide types, and consumers import only the stable names they need. This section uses named imports for root-level aliases; the guide's existing namespace-style examples remain useful when grouped access to the ambient module is clearer:

```tsx
import { RootAction, RootState, Services } from 'MyTypes';

// reducer(state: RootState, action: RootAction)
// Epic<RootAction, RootAction, RootState, Services>
```

The main benefit is that ownership stays local. When a feature is removed, its local exports and the corresponding root composition can be removed with it. Components, reducers, epics, and tests still get a consistent type vocabulary without every file needing to know where each root type is assembled.

[⇧ back to top](#table-of-contents)

### Create Store
Expand Down