// SPDX-FileCopyrightText: © 2024 LEDGER SAS // SPDX-License-Identifier: Apache-2.0 /** * Recursively makes all properties optional. * Arrays keep their element type (but each element is deeply partial). * Primitives and built-in value types (Date, RegExp) are preserved as-is. */ export type DeepPartial = T extends (infer U)[] ? DeepPartial[] : T extends Date | RegExp ? T : T extends object ? { [K in keyof T]?: DeepPartial } : T /** * Re-types a function so its return value is `DeepPartial>` (sync) * or `Promise>>>` (async), while keeping the * original parameter types intact. * * Use with `jest.mocked>(spy)` to let `mockReturnValue` / * `mockResolvedValue` accept partial stubs - no cast, no `any` at call sites. * * Works for both synchronous and asynchronous functions. * * @example * // Async: network module function mocked via jest.mock * import { broadcastTransaction } from './network' * jest.mock('./network', () => ({ broadcastTransaction: jest.fn() })) * * jest * .mocked>(broadcastTransaction) * .mockResolvedValue({ hash: 'abc123' }) // ✓ partial BroadcastResult accepted * * @example * // Sync: SDK client prototype method returning a fluent builder * // spyOn installs the spy; mocked re-types it - they cannot be combined * import { SdkClient } from './sdk' * * jest.spyOn(SdkClient.prototype, 'transactions') * const spy = jest.mocked>( * SdkClient.prototype.transactions * ) * spy.mockReturnValue({ forAccount: jest.fn().mockReturnThis(), call: jest.fn() }) // ✓ */ export type DeepPartialReturn unknown> = ReturnType extends Promise ? (...args: Parameters) => Promise> : (...args: Parameters) => DeepPartial> /** * Re-types a class constructor so that `mockImplementation` accepts a factory * returning a partial instance - `DeepPartial>` instead of the * full class - while keeping the original constructor parameter types. * * Use with `jest.mocked>(MyClass)` after * `jest.mock('./sdk')`. * * @example * import { SdkClient } from './sdk' * jest.mock('./sdk') * * jest.mocked>(SdkClient) * .mockImplementation(() => ({ * getBalance: jest.fn(), * getTransactions: jest.fn(), * })) // ✓ partial SdkClient instance accepted */ export type DeepPartialCtor unknown> = new ( ...args: ConstructorParameters ) => DeepPartial>