Skip to content

Commit 80912d0

Browse files
committed
refactor(hooks): route widened async params to the deprecated overloads
Replace the non-deprecated catch-all overloads with plain deprecated overloads (no async?: false pin): a params object whose async widened to boolean — or a value of the exported *Params types — now resolves to the deprecated overload instead of a warning-free catch-all. Since async is a member of the params types, such calls compile (no weak-type failure) and behave per the runtime value; the deprecation message tells the caller the fix: re-pin with { ...params, async: true }. This makes deprecation coverage total — any call not provably async: true is flagged — at the cost of a nudge for already-migrated callers who kept a widened object, which the message resolves. The type-compat tests keep pinning that these calls compile and run async at runtime, now with intentional no-deprecated disables.
1 parent cf99b1d commit 80912d0

2 files changed

Lines changed: 18 additions & 35 deletions

File tree

src/hooks/__tests__/useViewModelInstance.async.test.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,15 +367,18 @@ function createMockRiveViewRef(
367367
describe('useViewModelInstance - param type compatibility', () => {
368368
// These pin overload resolution as much as runtime behavior: a params
369369
// object built separately widens `async` to boolean, and the exported
370-
// params types declare `async?: boolean` — both must remain accepted
371-
// (`yarn tsc` is the gate that fails when the overloads regress).
370+
// params types declare `async?: boolean` — both must keep COMPILING and
371+
// behave per the runtime value (`yarn tsc` is the gate). By design they
372+
// resolve to the deprecated overloads: the warning's message tells such
373+
// callers to re-pin with `{ ...params, async: true }`.
372374
it('accepts a params object with a widened boolean async', async () => {
373375
const defaultInstance = createMockViewModelInstance();
374376
const defaultViewModel = createMockViewModel({ defaultInstance });
375377
const mockRiveFile = createMockRiveFile({ defaultViewModel });
376378

377379
const params = { async: true }; // widens to { async: boolean }
378380
const { result } = renderHook(() =>
381+
// eslint-disable-next-line @typescript-eslint/no-deprecated -- widened async resolves to the deprecated overload by design; runtime still honors the value
379382
useViewModelInstance(mockRiveFile, params)
380383
);
381384

@@ -391,6 +394,7 @@ describe('useViewModelInstance - param type compatibility', () => {
391394

392395
const params: UseViewModelInstanceFileParams = { async: true };
393396
const { result } = renderHook(() =>
397+
// eslint-disable-next-line @typescript-eslint/no-deprecated -- exported param types carry async?: boolean and resolve to the deprecated overload by design
394398
useViewModelInstance(mockRiveFile, params)
395399
);
396400

@@ -748,6 +752,7 @@ describe('useViewModelInstance - async flag constancy guard', () => {
748752

749753
const { rerender } = renderHook(
750754
({ isAsync }: { isAsync: boolean }) =>
755+
// eslint-disable-next-line @typescript-eslint/no-deprecated -- dynamic async is the misuse under test
751756
useViewModelInstance(mockRiveFile, { async: isAsync }),
752757
{ initialProps: { isAsync: false } }
753758
);

src/hooks/useViewModelInstance.ts

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -318,15 +318,15 @@ export function useViewModelInstance(
318318
source: RiveFile | null | undefined,
319319
params: UseViewModelInstanceFileParams & { async: true }
320320
): UseViewModelInstanceResult;
321-
/** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. */
321+
/** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. If your params object's `async` widened to `boolean`, re-pin it at the call site: `{ ...params, async: true }`. */
322322
export function useViewModelInstance(
323323
source: RiveFile,
324-
params: UseViewModelInstanceFileParams & { async?: false; required: true }
324+
params: UseViewModelInstanceFileParams & { required: true }
325325
): UseViewModelInstanceRequiredResult;
326-
/** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. */
326+
/** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. If your params object's `async` widened to `boolean`, re-pin it at the call site: `{ ...params, async: true }`. */
327327
export function useViewModelInstance(
328328
source: RiveFile | null | undefined,
329-
params?: UseViewModelInstanceFileParams & { async?: false }
329+
params?: UseViewModelInstanceFileParams
330330
): UseViewModelInstanceResult;
331331

332332
// ViewModel overloads
@@ -338,18 +338,15 @@ export function useViewModelInstance(
338338
source: ViewModel | null | undefined,
339339
params: UseViewModelInstanceViewModelParams & { async: true }
340340
): UseViewModelInstanceResult;
341-
/** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. */
341+
/** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. If your params object's `async` widened to `boolean`, re-pin it at the call site: `{ ...params, async: true }`. */
342342
export function useViewModelInstance(
343343
source: ViewModel,
344-
params: UseViewModelInstanceViewModelParams & {
345-
async?: false;
346-
required: true;
347-
}
344+
params: UseViewModelInstanceViewModelParams & { required: true }
348345
): UseViewModelInstanceRequiredResult;
349-
/** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. */
346+
/** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. If your params object's `async` widened to `boolean`, re-pin it at the call site: `{ ...params, async: true }`. */
350347
export function useViewModelInstance(
351348
source: ViewModel | null | undefined,
352-
params?: UseViewModelInstanceViewModelParams & { async?: false }
349+
params?: UseViewModelInstanceViewModelParams
353350
): UseViewModelInstanceResult;
354351

355352
// RiveViewRef overloads
@@ -361,31 +358,12 @@ export function useViewModelInstance(
361358
source: RiveViewRef | null | undefined,
362359
params: UseViewModelInstanceRefParams & { async: true }
363360
): UseViewModelInstanceResult;
364-
/** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. */
361+
/** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. If your params object's `async` widened to `boolean`, re-pin it at the call site: `{ ...params, async: true }`. */
365362
export function useViewModelInstance(
366363
source: RiveViewRef,
367-
params: UseViewModelInstanceRefParams & { async?: false; required: true }
364+
params: UseViewModelInstanceRefParams & { required: true }
368365
): UseViewModelInstanceRequiredResult;
369-
/** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. */
370-
export function useViewModelInstance(
371-
source: RiveViewRef | null | undefined,
372-
params?: UseViewModelInstanceRefParams & { async?: false }
373-
): UseViewModelInstanceResult;
374-
375-
// Widened-`async` catch-alls: a params object built separately (or typed
376-
// with the exported *Params types) carries `async?: boolean` and matches no
377-
// literal overload above — without these the compiler rejects the call and
378-
// blames the *source* argument. The flag still must stay constant for the
379-
// component's lifetime. Literal `async` values resolve to the more specific
380-
// overloads first, keeping the deprecation warnings and `required` narrowing.
381-
export function useViewModelInstance(
382-
source: RiveFile | null | undefined,
383-
params?: UseViewModelInstanceFileParams
384-
): UseViewModelInstanceResult;
385-
export function useViewModelInstance(
386-
source: ViewModel | null | undefined,
387-
params?: UseViewModelInstanceViewModelParams
388-
): UseViewModelInstanceResult;
366+
/** @deprecated Pass `async: true` — without it the instance is created synchronously via deprecated runtime APIs that block the JS thread. `async: true` becomes the default in the next major. If your params object's `async` widened to `boolean`, re-pin it at the call site: `{ ...params, async: true }`. */
389367
export function useViewModelInstance(
390368
source: RiveViewRef | null | undefined,
391369
params?: UseViewModelInstanceRefParams

0 commit comments

Comments
 (0)