From 9c18598653652ffae3cdd4d9915a2941e3e92dd2 Mon Sep 17 00:00:00 2001 From: JoostK Date: Sun, 8 Mar 2026 11:52:40 +0100 Subject: [PATCH] refactor(core): declare explicit reactive node prototypes types These type annotations allow TS to associate the object's properties with their corresponding declaration in the interfaces, enabling much better code navigation. For example, "Find all implementations" for `ReactiveNode.producerRecomputeValue` now finds the implementation in `COMPUTED_NODE` and `LINKED_SIGNAL_NODE`. --- packages/core/primitives/signals/src/computed.ts | 2 +- packages/core/primitives/signals/src/linked_signal.ts | 5 ++++- packages/core/primitives/signals/src/watch.ts | 2 +- packages/core/src/render3/reactivity/after_render_effect.ts | 5 ++++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/core/primitives/signals/src/computed.ts b/packages/core/primitives/signals/src/computed.ts index 96f1e93af6b1..9efdae12ddbb 100644 --- a/packages/core/primitives/signals/src/computed.ts +++ b/packages/core/primitives/signals/src/computed.ts @@ -114,7 +114,7 @@ export const ERRORED: any = /* @__PURE__ */ Symbol('ERRORED'); // Note: Using an IIFE here to ensure that the spread assignment is not considered // a side-effect, ending up preserving `COMPUTED_NODE` and `REACTIVE_NODE`. -const COMPUTED_NODE = /* @__PURE__ */ (() => { +const COMPUTED_NODE: Omit, 'computation'> = /* @__PURE__ */ (() => { return { ...REACTIVE_NODE, value: UNSET, diff --git a/packages/core/primitives/signals/src/linked_signal.ts b/packages/core/primitives/signals/src/linked_signal.ts index 14434c58581f..dff857add277 100644 --- a/packages/core/primitives/signals/src/linked_signal.ts +++ b/packages/core/primitives/signals/src/linked_signal.ts @@ -123,7 +123,10 @@ export function linkedSignalUpdateFn( // Note: Using an IIFE here to ensure that the spread assignment is not considered // a side-effect, ending up preserving `LINKED_SIGNAL_NODE` and `REACTIVE_NODE`. -export const LINKED_SIGNAL_NODE: object = /* @__PURE__ */ (() => { +export const LINKED_SIGNAL_NODE: Omit< + LinkedSignalNode, + 'computation' | 'source' | 'sourceValue' +> = /* @__PURE__ */ (() => { return { ...REACTIVE_NODE, value: UNSET, diff --git a/packages/core/primitives/signals/src/watch.ts b/packages/core/primitives/signals/src/watch.ts index e9c3f3680397..56eea164ecb1 100644 --- a/packages/core/primitives/signals/src/watch.ts +++ b/packages/core/primitives/signals/src/watch.ts @@ -140,7 +140,7 @@ const NOOP_CLEANUP_FN: WatchCleanupFn = () => {}; // Note: Using an IIFE here to ensure that the spread assignment is not considered // a side-effect, ending up preserving `COMPUTED_NODE` and `REACTIVE_NODE`. -const WATCH_NODE: Partial = /* @__PURE__ */ (() => { +const WATCH_NODE: Omit = /* @__PURE__ */ (() => { return { ...REACTIVE_NODE, consumerIsAlwaysLive: true, diff --git a/packages/core/src/render3/reactivity/after_render_effect.ts b/packages/core/src/render3/reactivity/after_render_effect.ts index 7d3493f4797f..3230e056a29e 100644 --- a/packages/core/src/render3/reactivity/after_render_effect.ts +++ b/packages/core/src/render3/reactivity/after_render_effect.ts @@ -77,7 +77,10 @@ export interface AfterRenderPhaseEffectNode extends SignalNode { phaseFn(previousValue?: unknown): unknown; } -const AFTER_RENDER_PHASE_EFFECT_NODE = /* @__PURE__ */ (() => ({ +const AFTER_RENDER_PHASE_EFFECT_NODE: Omit< + AfterRenderPhaseEffectNode, + 'phase' | 'sequence' | 'userFn' | 'signal' | 'registerCleanupFn' +> = /* @__PURE__ */ (() => ({ ...SIGNAL_NODE, kind: 'afterRenderEffectPhase', consumerIsAlwaysLive: true,