From f1342859cbcfeaff41ca9a2e327520a7bf6bf698 Mon Sep 17 00:00:00 2001 From: Ahmed Yasin Koculu Date: Sun, 22 Feb 2026 09:46:06 +0100 Subject: [PATCH 1/4] bivarianceHack to remove any from AnyRef --- src/api/types.ts | 29 ++++++++++++++--------------- src/observer/observe.ts | 2 +- src/parser/regorEval.ts | 32 ++++++++++++++++---------------- src/reactivity/sref.ts | 2 +- 4 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/api/types.ts b/src/api/types.ts index 1910cd1..52bb91d 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -28,30 +28,29 @@ type RawTypes = | Promise | Error -declare const RefSymbol: unique symbol - declare const RawSymbol: unique symbol declare const ScopeSymbol: unique symbol -export type AnyRef = ( - newValue?: any, - eventSource?: any, -) => any & { [RefSymbol]: true } +type BivariantAnyRefCall = { + bivarianceHack(newValue?: unknown, eventSource?: unknown): unknown +}['bivarianceHack'] + +export type AnyRef = BivariantAnyRefCall export type Ref = (( newValue?: | RefContent | Ref> | SRef>, - eventSource?: any, + eventSource?: unknown, ) => RefContent) & { value: RefContent } export type SRef = (( newValue?: TValueType | SRef, - eventSource?: any, + eventSource?: unknown, ) => SRefContent) & { value: SRefContent } @@ -155,7 +154,7 @@ export type Flat = export type ObserveCallback = ( newValue: TValueType, - eventSource?: any, + eventSource?: unknown, ) => void export type StopObserving = () => void @@ -182,10 +181,10 @@ export interface Directive { /** Called on every value change. */ onChange?: ( el: HTMLElement, - values: any[], - previousValues?: any[], - option?: any, - previousOption?: any, + values: unknown[], + previousValues?: unknown[], + option?: unknown, + previousOption?: unknown, flags?: string[], ) => void @@ -369,10 +368,10 @@ export interface ComposableScope { */ export type SRefSignature = ( newValue?: TValueType, - eventSource?: any, + eventSource?: unknown, operation?: RefOperation, observer?: ObserveCallback, -) => any +) => unknown /** * @internal diff --git a/src/observer/observe.ts b/src/observer/observe.ts index a9acbe2..76cb60b 100644 --- a/src/observer/observe.ts +++ b/src/observer/observe.ts @@ -17,7 +17,7 @@ export const observe = ( ): StopObserving => { if (!isRef(source)) throw getError(ErrorType.RequiresRefSourceArgument, 'observe') - if (init) observer(source()) + if (init) observer(source() as UnwrapRef) const srefImpl = source as unknown as SRefSignature> const stop = srefImpl( undefined, diff --git a/src/parser/regorEval.ts b/src/parser/regorEval.ts index aedb0d3..2af0726 100644 --- a/src/parser/regorEval.ts +++ b/src/parser/regorEval.ts @@ -108,7 +108,7 @@ const evalPrefixUpdate = { '++': (context: Context, key: any) => { const v = context[key] if (isRef(v)) { - let r = v() + let r = v() as any v(++r) return r } @@ -117,7 +117,7 @@ const evalPrefixUpdate = { '--': (context: Context, key: any) => { const v = context[key] if (isRef(v)) { - let r = v() + let r = v() as any v(--r) return r } @@ -129,7 +129,7 @@ const evalPostUpdate = { '++': (context: Context, key: any) => { const v = context[key] if (isRef(v)) { - const r = v() + const r = v() as any v(r + 1) return r @@ -139,7 +139,7 @@ const evalPostUpdate = { '--': (context: Context, key: any) => { const v = context[key] if (isRef(v)) { - const r = v() + const r = v() as any v(r - 1) return r } @@ -157,7 +157,7 @@ const applyAssigment = { '+=': (context: Context, key: any, value: any) => { const v = context[key] if (isRef(v)) { - return v(v() + value) + return v((v() as any) + value) } return (context[key] += value) @@ -165,77 +165,77 @@ const applyAssigment = { '-=': (context: Context, key: any, value: any) => { const v = context[key] if (isRef(v)) { - return v(v() - value) + return v((v() as any) - value) } return (context[key] -= value) }, '*=': (context: Context, key: any, value: any) => { const v = context[key] if (isRef(v)) { - return v(v() * value) + return v((v() as any) * value) } return (context[key] *= value) }, '/=': (context: Context, key: any, value: any) => { const v = context[key] if (isRef(v)) { - return v(v() / value) + return v((v() as any) / value) } return (context[key] /= value) }, '%=': (context: Context, key: any, value: any) => { const v = context[key] if (isRef(v)) { - return v(v() % value) + return v((v() as any) % value) } return (context[key] %= value) }, '**=': (context: Context, key: any, value: any) => { const v = context[key] if (isRef(v)) { - return v(v() ** value) + return v((v() as any) ** value) } return (context[key] **= value) }, '<<=': (context: Context, key: any, value: any) => { const v = context[key] if (isRef(v)) { - return v(v() << value) + return v((v() as any) << value) } return (context[key] <<= value) }, '>>=': (context: Context, key: any, value: any) => { const v = context[key] if (isRef(v)) { - return v(v() >> value) + return v((v() as any) >> value) } return (context[key] >>= value) }, '>>>=': (context: Context, key: any, value: any) => { const v = context[key] if (isRef(v)) { - return v(v() >>> value) + return v((v() as any) >>> value) } return (context[key] >>>= value) }, '|=': (context: Context, key: any, value: any) => { const v = context[key] if (isRef(v)) { - return v(v() | value) + return v((v() as any) | value) } return (context[key] |= value) }, '&=': (context: Context, key: any, value: any) => { const v = context[key] if (isRef(v)) { - return v(v() & value) + return v((v() as any) & value) } return (context[key] &= value) }, '^=': (context: Context, key: any, value: any) => { const v = context[key] if (isRef(v)) { - return v(v() ^ value) + return v((v() as any) ^ value) } return (context[key] ^= value) }, diff --git a/src/reactivity/sref.ts b/src/reactivity/sref.ts index 124eab2..a0123f4 100644 --- a/src/reactivity/sref.ts +++ b/src/reactivity/sref.ts @@ -112,7 +112,7 @@ export const sref = ( if (0 in args) { if (refObj._value === newValue) return newValue if (isRef(newValue)) { - newValue = newValue() + newValue = newValue() as TValueType if (refObj._value === newValue) return newValue } From 304642d3fc96c784f2b626a41b52b91fdbe59a0e Mon Sep 17 00:00:00 2001 From: Ahmed Yasin Koculu Date: Sun, 22 Feb 2026 10:08:35 +0100 Subject: [PATCH 2/4] remove any from public types. --- src/api/types.ts | 2 +- src/cleanup/getBindData.ts | 9 ++- src/computed/computeMany.ts | 26 ++++--- src/log/warnings.ts | 4 +- src/misc/isRaw.ts | 4 +- src/misc/tagged-html.ts | 2 +- src/observer/observeMany.ts | 14 ++-- src/reactivity/trigger.ts | 2 +- tests/computed/computeMany.spec.ts | 119 +++++++++++++++++++++++++++++ tests/observer/observeMany.spec.ts | 35 +++++++++ tests/reactivity/trigger.spec.ts | 101 ++++++++++++++++++++++++ 11 files changed, 295 insertions(+), 23 deletions(-) create mode 100644 tests/computed/computeMany.spec.ts create mode 100644 tests/reactivity/trigger.spec.ts diff --git a/src/api/types.ts b/src/api/types.ts index 52bb91d..e0ac0fc 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -338,7 +338,7 @@ export interface CreateComponentOptions< * The props defined in the props list can be used with :foo or r-bind:foo syntax. * ` { const createdAt = ref(new Date('2025-01-01T00:00:00.000Z')) const calls: string[] = [] - const stop = observeMany([label, count, createdAt], ([l, c, d]) => { - calls.push(`${l}:${c}:${d.getUTCFullYear()}`) - }, true) + const stop = observeMany( + [label, count, createdAt], + ([l, c, d]) => { + calls.push(`${l}:${c}:${d.getUTCFullYear()}`) + }, + true, + ) expect(calls).toStrictEqual(['v1:2:2025']) From a5ebb18f084f4160b50639a4149b94785ffa2328 Mon Sep 17 00:00:00 2001 From: Ahmed Yasin Koculu Date: Sun, 22 Feb 2026 10:11:13 +0100 Subject: [PATCH 4/4] split type names. --- src/computed/computeMany.ts | 10 ++++++---- src/observer/observeMany.ts | 8 +++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/computed/computeMany.ts b/src/computed/computeMany.ts index 7944a06..8042b45 100644 --- a/src/computed/computeMany.ts +++ b/src/computed/computeMany.ts @@ -13,7 +13,7 @@ import { sref } from '../reactivity/sref' import { trigger } from '../reactivity/trigger' import { type ComputedOnce } from './computed' -type SourceValues = { +type ComputeManySourceValues = { [TIndex in keyof TSources]: UnwrapRef } @@ -22,7 +22,7 @@ export const computeMany = < TReturnType, >( sources: TSources, - compute: (...values: SourceValues) => TReturnType, + compute: (...values: ComputeManySourceValues) => TReturnType, ): ComputedRef> => { const status: ComputedOnce = {} let computer: any @@ -43,7 +43,7 @@ export const computeMany = < const computeManyOnce = ( sources: TSources, - compute: (...values: SourceValues) => TReturnType, + compute: (...values: ComputeManySourceValues) => TReturnType, status: ComputedOnce, ): ComputedRef> => { const result = @@ -61,7 +61,9 @@ const computeManyOnce = ( trigger(result) return } - const values = sources.map((source) => source()) as SourceValues + const values = sources.map((source) => + source(), + ) as ComputeManySourceValues result(compute(...values) as UnwrapRef) ++i } diff --git a/src/observer/observeMany.ts b/src/observer/observeMany.ts index ee35f79..7c9c698 100644 --- a/src/observer/observeMany.ts +++ b/src/observer/observeMany.ts @@ -2,18 +2,20 @@ import { type AnyRef, type StopObserving, type UnwrapRef } from '../api/types' import { onUnmounted } from '../composition/onUnmounted' import { observe } from './observe' -type SourceValues = { +type ObserveManySourceValues = { [TIndex in keyof TSources]: UnwrapRef } export const observeMany = ( sources: TSources, - observer: (values: SourceValues) => void, + observer: (values: ObserveManySourceValues) => void, init?: boolean, ): StopObserving => { const stopObservingList: StopObserving[] = [] const callObserver = (): void => { - observer(sources.map((source) => source()) as SourceValues) + observer( + sources.map((source) => source()) as ObserveManySourceValues, + ) } for (const source of sources) { stopObservingList.push(observe(source, callObserver))