Skip to content

fix: Extend generic signature improvements to safe wrapper functions - #498

Merged
nev21 merged 1 commit into
mainfrom
nev21/GenericSig
Feb 3, 2026
Merged

nev21 merged 1 commit into
mainfrom
nev21/GenericSig

Conversation

@nev21

@nev21 nev21 commented Feb 2, 2026

Copy link
Copy Markdown
Contributor
  • Update safe() to use ReturnType instead of any for better type inference
  • Align safeGet, safeGetLazy, safeGetWritableLazy, safeGetDeferred, and safeGetWritableDeferred with the same flexible callback signature pattern
  • Change default type parameter from () => T to (...args: any[]) => T
  • Add union type to callback parameters: cb: F | ((...args: Parameters) => T)
  • Remove unnecessary default (T = boolean) from safeGet
  • Fix typo in safeGetWritableLazy documentation

Extends the type flexibility improvements from #497 to all safe wrapper functions for consistent API patterns and better type inference across the library.

@nev21 nev21 added this to the 0.12.6 milestone Feb 2, 2026
@nev21
nev21 requested a review from a team as a code owner February 2, 2026 17:43
Copilot AI review requested due to automatic review settings February 2, 2026 17:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends the generic type signature improvements from #497 to the safe() / safeGet*() wrappers to improve type inference and align callback signatures across the “safe” helpers.

Changes:

  • Update safe() to default its return type to ReturnType<F> instead of any.
  • Align safeGet, safeGetLazy, safeGetWritableLazy, safeGetDeferred, and safeGetWritableDeferred to the more flexible callback signature pattern (F | ((...args: Parameters<F>) => T)), and adjust generic defaults.
  • Fix a typo in the safeGetWritableLazy documentation example.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
lib/src/helpers/safe.ts Tightens safe() typing by defaulting the return type to ReturnType<F>.
lib/src/helpers/safe_get.ts Updates safeGet() generics/callback signature pattern for better inference and consistency.
lib/src/helpers/safe_lazy.ts Applies the same signature pattern to lazy/deferred safe wrappers and fixes a doc typo.
Comments suppressed due to low confidence (5)

lib/src/helpers/safe_lazy.ts:93

  • With safe() now defaulting to ReturnType<F>, result.v is typed as T | undefined (since ISafeReturn.v is optional). The callback passed to getWritableLazy<T> returns result.v on the non-error branch, making it T | undefined and likely breaking type-checking. Fix by updating ISafeReturn/safe() to narrow v when no error, or normalize/assert the non-error branch before returning.
export function safeGetWritableLazy<T = boolean, F extends (...args: any[]) => T = (...args: any[]) => T>(cb: F | ((...args: Parameters<F>) => T), defValue: T, argArray?: Parameters<F>): ILazyValue<T> {
    return getWritableLazy<T>(() => {
        let result = safe(cb, argArray);
        return result.e ? defValue : result.v;
    });

lib/src/helpers/safe_lazy.ts:137

  • With safe() now defaulting to ReturnType<F>, result.v is typed as T | undefined (since ISafeReturn.v is optional). The callback passed into getDeferred<T, () => T> returns result.v on the non-error branch, making it T | undefined and likely breaking type-checking. Fix by updating ISafeReturn/safe() to narrow v when no error, or normalize/assert the non-error branch before returning.
export function safeGetDeferred<T, F extends (...args: any[]) => T = (...args: any[]) => T>(cb: F | ((...args: Parameters<F>) => T), defValue: T, argArray?: Parameters<F>): ICachedValue<T> {
    return getDeferred<T, () => T>(() => {
        let result = safe(cb, argArray);
        return result.e ? defValue : result.v;
    });

lib/src/helpers/safe_lazy.ts:185

  • With safe() now defaulting to ReturnType<F>, result.v is typed as T | undefined (since ISafeReturn.v is optional). The callback passed into getWritableDeferred<T, () => T> returns result.v on the non-error branch, making it T | undefined and likely breaking type-checking. Fix by updating ISafeReturn/safe() to narrow v when no error, or normalize/assert the non-error branch before returning.
export function safeGetWritableDeferred<T, F extends (...args: any[]) => T = (...args: any[]) => T>(cb: F | ((...args: Parameters<F>) => T), defValue: T, argArray?: Parameters<F>): ICachedValue<T> {
    return getWritableDeferred<T, () => T>(() => {
        let result = safe(cb, argArray);
        return result.e ? defValue : result.v;
    });

lib/src/helpers/safe.ts:70

  • The new default generic R = ReturnType<F> makes result.v in callers typed as ReturnType<F> | undefined (because ISafeReturn.v is optional). Callers like safeGet*() return result.v directly, so this change is likely to break TypeScript compilation (returning T | undefined where T is expected). Consider updating ISafeReturn to a discriminated union (value vs error) so that result.e narrows result.v, or otherwise adjust safe()/call sites to handle the optional v safely.
export function safe<F extends (...args: unknown[]) => R, R = ReturnType<F>>(func: F, argArray?: any[]): ISafeReturn<F, R> {
    try {
        return {
            v: func.apply(this, argArray)
        };
    } catch (e) {
        return { e };
    }

lib/src/helpers/safe_lazy.ts:49

  • With safe() now defaulting to ReturnType<F>, result.v is typed as T | undefined (since ISafeReturn.v is optional). The non-error branch returns result.v, so the callback passed to getLazy<T> becomes () => T | undefined, which is incompatible with T and likely breaks type-checking. Fix by updating ISafeReturn/safe() to narrow v when no error, or normalize/assert the non-error branch before returning.
export function safeGetLazy<T = boolean, F extends (...args: any[]) => T = (...args: any[]) => T>(cb: F | ((...args: Parameters<F>) => T), defValue: T, argArray?: Parameters<F>): ILazyValue<T> {
    return getLazy<T>(() => {
        let result = safe(cb, argArray);
        return result.e ? defValue : result.v;
    });

Comment thread lib/src/helpers/safe_lazy.ts Resolved
Comment thread lib/src/helpers/safe_lazy.ts Resolved
Comment thread lib/src/helpers/safe_get.ts Resolved
@codecov

codecov Bot commented Feb 2, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.89%. Comparing base (d3886de) to head (9a89995).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #498   +/-   ##
=======================================
  Coverage   98.89%   98.89%           
=======================================
  Files         108      108           
  Lines        2981     2981           
  Branches      645      622   -23     
=======================================
  Hits         2948     2948           
  Misses         33       33           
Files with missing lines Coverage Δ
lib/src/helpers/safe.ts 100.00% <100.00%> (ø)
lib/src/helpers/safe_get.ts 100.00% <100.00%> (ø)
lib/src/helpers/safe_lazy.ts 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- Update safe() to use ReturnType<F> instead of any for better type inference
- Align safeGet, safeGetLazy, safeGetWritableLazy, safeGetDeferred, and
  safeGetWritableDeferred with the same flexible callback signature pattern
- Change default type parameter from () => T to (...args: any[]) => T
- Add union type to callback parameters: cb: F | ((...args: Parameters<F>) => T)
- Remove unnecessary default (T = boolean) from safeGet
- Fix typo in safeGetWritableLazy documentation

Extends the type flexibility improvements from #497 to all safe wrapper
functions for consistent API patterns and better type inference across
the library.
@nev21
nev21 merged commit 0bcf1c9 into main Feb 3, 2026
12 checks passed
@nev21
nev21 deleted the nev21/GenericSig branch February 3, 2026 06:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants