2626 * `TServiceParams` merges contributions with priority:
2727 * direct `LoadedModules` wins over `Omit<RollupApis, keyof LoadedModules>`.
2828 *
29- * ─── declaration-emit discipline ─────────────────────────────────────────────
30- * The shipped `.d.ts` is emitted by `yarn build` (`tsc -p tsconfig.lib.json`),
31- * which sets `declaration: true` and `isolatedModules: true` — it does NOT set
32- * `isolatedDeclarations`. All service factories in this file are nonetheless
33- * written as named `function` declarations with explicit return type annotations
34- * — the form that emits a `typeof` import reference in `.d.ts` (and would also be
35- * valid if `isolatedDeclarations` were ever enabled). The `const`-arrow in
36- * Case 3 is the intentional negative example.
29+ * ─── isolatedDeclarations discipline ────────────────────────────────────────
30+ * All service factories in this file are named `function` declarations with
31+ * explicit return type annotations — the form that emits a `typeof` import
32+ * reference in `.d.ts` (and is valid under `isolatedDeclarations`). The
33+ * `const`-arrow in Case 3 is the intentional negative example.
3734 * ─────────────────────────────────────────────────────────────────────────────
3835 */
3936
@@ -301,10 +298,9 @@ export type _Assert_Case3_KeyAbsentFromTServiceParams = TServiceParams["const_ar
301298// ═══════════════════════════════════════════════════════════════════════════════
302299// CASE 4 FIXTURES
303300//
304- // FAN-OUT SANITY under the shipped declaration-emit config (tsconfig.lib.json:
305- // declaration: true, isolatedModules: true — not isolatedDeclarations): one base
306- // library depended-on by many others. Proves no TS2456 (circular reference),
307- // no emit explosion, and all types resolve correctly at real `depends` density.
301+ // FAN-OUT SANITY under isolatedDeclarations: one base library depended-on by
302+ // many others. Proves no TS2456 (circular reference), no emit explosion, and
303+ // all types resolve correctly at real `depends` density.
308304//
309305// The gating risk from commit 2a3006c: with `const Depends` capture, each
310306// library's `.d.ts` emits typed references to its deps. At high fan-in density
@@ -328,8 +324,8 @@ export const LIB_FANOUT_BASE = CreateLibrary({
328324 services : { FanOutBaseService } ,
329325} ) ;
330326
331- export function FanOutConsumerAService ( _params : TServiceParams ) : { a : string } {
332- return { a : " true" } ;
327+ export function FanOutConsumerAService ( _params : TServiceParams ) : { a : boolean } {
328+ return { a : true } ;
333329}
334330export const LIB_FANOUT_A = CreateLibrary ( {
335331 depends : [ LIB_FANOUT_BASE ] ,
@@ -385,12 +381,23 @@ export type _Assert_Case4_FanOutBasePing = ExpectTrue<
385381 TypeEqual < GetApisResult < ( typeof LIB_FANOUT_BASE ) [ "services" ] > [ "FanOutBaseService" ] [ "ping" ] , ( ) => string >
386382> ;
387383
388- /** All four sibling consumer services resolve correctly — no type collapse from fan-out. */
389- export type _Assert_Case4_AllSiblingsPresent = ExpectTrue <
390- TypeEqual < GetApisResult < ( typeof LIB_FANOUT_A ) [ "services" ] > [ "FanOutConsumerAService" ] [ "a" ] , boolean > &
391- TypeEqual < GetApisResult < ( typeof LIB_FANOUT_B ) [ "services" ] > [ "FanOutConsumerBService" ] [ "b" ] , boolean > &
392- TypeEqual < GetApisResult < ( typeof LIB_FANOUT_C ) [ "services" ] > [ "FanOutConsumerCService" ] [ "c" ] , boolean > &
393- TypeEqual < GetApisResult < ( typeof LIB_FANOUT_D ) [ "services" ] > [ "FanOutConsumerDService" ] [ "d" ] , boolean >
384+ /**
385+ * Each sibling consumer service resolves correctly — no type collapse from fan-out.
386+ * NOTE: We use separate type aliases rather than intersecting boolean literals,
387+ * because `false & true` evaluates to `never` in TypeScript, and `never extends true`
388+ * is vacuously true — which would mask a failing assertion.
389+ */
390+ export type _Assert_Case4_SiblingA = ExpectTrue <
391+ TypeEqual < GetApisResult < ( typeof LIB_FANOUT_A ) [ "services" ] > [ "FanOutConsumerAService" ] [ "a" ] , boolean >
392+ > ;
393+ export type _Assert_Case4_SiblingB = ExpectTrue <
394+ TypeEqual < GetApisResult < ( typeof LIB_FANOUT_B ) [ "services" ] > [ "FanOutConsumerBService" ] [ "b" ] , boolean >
395+ > ;
396+ export type _Assert_Case4_SiblingC = ExpectTrue <
397+ TypeEqual < GetApisResult < ( typeof LIB_FANOUT_C ) [ "services" ] > [ "FanOutConsumerCService" ] [ "c" ] , boolean >
398+ > ;
399+ export type _Assert_Case4_SiblingD = ExpectTrue <
400+ TypeEqual < GetApisResult < ( typeof LIB_FANOUT_D ) [ "services" ] > [ "FanOutConsumerDService" ] [ "d" ] , boolean >
394401> ;
395402
396403/** LIB_FANOUT_E (5-entry Depends tuple) compiles without circular reference or type collapse. */
@@ -402,14 +409,13 @@ export type _Assert_Case4_FanOutEPresent = ExpectTrue<
402409 * LIB_FANOUT_E's `Depends` tuple retains all 5 literal element types.
403410 * If the tuple collapsed to `readonly TLibrary[]`, these would be `TLibrary` (wider),
404411 * and `Extends<typeof LIB_FANOUT_A, ...>` would fail.
412+ * Each position is checked separately to avoid the `false & true = never` masking problem.
405413 */
406- export type _Assert_Case4_FanOutEDependsRetainsLiterals = ExpectTrue <
407- Extends < typeof LIB_FANOUT_BASE , ( typeof LIB_FANOUT_E ) [ "depends" ] [ 0 ] > &
408- Extends < typeof LIB_FANOUT_A , ( typeof LIB_FANOUT_E ) [ "depends" ] [ 1 ] > &
409- Extends < typeof LIB_FANOUT_B , ( typeof LIB_FANOUT_E ) [ "depends" ] [ 2 ] > &
410- Extends < typeof LIB_FANOUT_C , ( typeof LIB_FANOUT_E ) [ "depends" ] [ 3 ] > &
411- Extends < typeof LIB_FANOUT_D , ( typeof LIB_FANOUT_E ) [ "depends" ] [ 4 ] >
412- > ;
414+ export type _Assert_Case4_Dep0 = ExpectTrue < Extends < typeof LIB_FANOUT_BASE , ( typeof LIB_FANOUT_E ) [ "depends" ] [ 0 ] > > ;
415+ export type _Assert_Case4_Dep1 = ExpectTrue < Extends < typeof LIB_FANOUT_A , ( typeof LIB_FANOUT_E ) [ "depends" ] [ 1 ] > > ;
416+ export type _Assert_Case4_Dep2 = ExpectTrue < Extends < typeof LIB_FANOUT_B , ( typeof LIB_FANOUT_E ) [ "depends" ] [ 2 ] > > ;
417+ export type _Assert_Case4_Dep3 = ExpectTrue < Extends < typeof LIB_FANOUT_C , ( typeof LIB_FANOUT_E ) [ "depends" ] [ 3 ] > > ;
418+ export type _Assert_Case4_Dep4 = ExpectTrue < Extends < typeof LIB_FANOUT_D , ( typeof LIB_FANOUT_E ) [ "depends" ] [ 4 ] > > ;
413419
414420// ═══════════════════════════════════════════════════════════════════════════════
415421// RUNTIME SUITE
@@ -473,7 +479,7 @@ describe("cross-package type-travel via depends/implies (compile-time proof)", (
473479 } ) ;
474480
475481 // ── Case 4 ────────────────────────────────────────────────────────────────
476- describe ( "Case 4 — fan-out: base depended-on by many libs; declaration emit stays sane" , ( ) => {
482+ describe ( "Case 4 — fan-out: base depended-on by many libs; isolatedDeclarations stays sane" , ( ) => {
477483 it ( "all six fanout libraries have unique names" , ( ) => {
478484 const names = [
479485 LIB_FANOUT_BASE . name ,
@@ -495,9 +501,8 @@ describe("cross-package type-travel via depends/implies (compile-time proof)", (
495501 } ) ;
496502
497503 it ( "compile-time: 5-dep fan-out compiles without TS2456 or type collapse" , ( ) => {
498- // _Assert_Case4_FanOutBasePing, _Assert_Case4_AllSiblingsPresent,
499- // _Assert_Case4_FanOutEPresent, _Assert_Case4_FanOutEDependsRetainsLiterals
500- // all hold under `yarn type-check`.
504+ // _Assert_Case4_FanOutBasePing, _Assert_Case4_Sibling*, _Assert_Case4_FanOutEPresent,
505+ // _Assert_Case4_Dep* all hold under `yarn type-check`.
501506 expect ( LIB_FANOUT_BASE . services . FanOutBaseService ) . toBeDefined ( ) ;
502507 expect ( LIB_FANOUT_E . services . FanOutConsumerEService ) . toBeDefined ( ) ;
503508 } ) ;
0 commit comments