From 7f81e1f7353997bd031aaac6920b9b09f883da36 Mon Sep 17 00:00:00 2001 From: ProtonsAndElectrons <143947806+ProtonsAndElectrons@users.noreply.github.com> Date: Wed, 20 May 2026 14:45:33 +0200 Subject: [PATCH 1/3] docs: explain Types global namespace --- README.md | 27 +++++++++++++++++++++++++++ README_SOURCE.md | 22 ++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/README.md b/README.md index 647b5c7..193c7af 100644 --- a/README.md +++ b/README.md @@ -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) @@ -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; +} + +``` + +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: + +```ts +import { RootAction, RootState, Services } from 'MyTypes'; + +// reducer(state: RootState, action: RootAction) +// Epic +``` + +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 diff --git a/README_SOURCE.md b/README_SOURCE.md index 358fcc3..e7249b8 100644 --- a/README_SOURCE.md +++ b/README_SOURCE.md @@ -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) @@ -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: + +```ts +import { RootAction, RootState, Services } from 'MyTypes'; + +// reducer(state: RootState, action: RootAction) +// Epic +``` + +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 From dbf56bd03851a23f41d79e4b2f65a3868fb326ac Mon Sep 17 00:00:00 2001 From: ProtonsAndElectrons <143947806+ProtonsAndElectrons@users.noreply.github.com> Date: Wed, 20 May 2026 17:41:43 +0200 Subject: [PATCH 2/3] docs: clarify MyTypes import style --- README.md | 4 ++-- README_SOURCE.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 193c7af..91f75e0 100644 --- a/README.md +++ b/README.md @@ -1327,9 +1327,9 @@ declare module 'MyTypes' { 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 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. Use named imports for these root-level aliases; examples that need grouped access to the ambient module can still import the `MyTypes` namespace: -```ts +```tsx import { RootAction, RootState, Services } from 'MyTypes'; // reducer(state: RootState, action: RootAction) diff --git a/README_SOURCE.md b/README_SOURCE.md index e7249b8..e870671 100644 --- a/README_SOURCE.md +++ b/README_SOURCE.md @@ -527,9 +527,9 @@ Each application area extends this module from the place that owns the type. The 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 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. Use named imports for these root-level aliases; examples that need grouped access to the ambient module can still import the `MyTypes` namespace: -```ts +```tsx import { RootAction, RootState, Services } from 'MyTypes'; // reducer(state: RootState, action: RootAction) From 1bcd2c833825be04fca49e87c691422de2e0faef Mon Sep 17 00:00:00 2001 From: ProtonsAndElectrons <143947806+ProtonsAndElectrons@users.noreply.github.com> Date: Thu, 21 May 2026 04:38:26 +0200 Subject: [PATCH 3/3] docs: align MyTypes import guidance --- README.md | 2 +- README_SOURCE.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 91f75e0..aa6314e 100644 --- a/README.md +++ b/README.md @@ -1327,7 +1327,7 @@ declare module 'MyTypes' { 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. Use named imports for these root-level aliases; examples that need grouped access to the ambient module can still import the `MyTypes` namespace: +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'; diff --git a/README_SOURCE.md b/README_SOURCE.md index e870671..c05e8b2 100644 --- a/README_SOURCE.md +++ b/README_SOURCE.md @@ -527,7 +527,7 @@ Each application area extends this module from the place that owns the type. The 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. Use named imports for these root-level aliases; examples that need grouped access to the ambient module can still import the `MyTypes` namespace: +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';