Repository: facebook/jest
File: packages/jest-mock/src/index.ts (TypeScript)

Code before:
  ? unknown
  : never;

type WithImplementationSyncCallbackReturn = void | undefined;
type WithImplementationAsyncCallbackReturn = Promise<unknown>;
type WithImplementationCallbackReturn =
  | WithImplementationSyncCallbackReturn
  | WithImplementationAsyncCallbackReturn;

export interface MockInstance<T extends FunctionLike = UnknownFunction> {
  _isMockFunction: true;
  _protoImpl: Function;
  getMockImplementation(): T | undefined;
  getMockName(): string;
  mock: MockFunctionState<T>;
  mockClear(): this;
  mockReset(): this;
  mockRestore(): void;
  mockImplementation(fn: T): this;
  mockImplementationOnce(fn: T): this;
  withImplementation<R extends WithImplementationCallbackReturn>(
    fn: T,
    callback: () => R,
  ): R extends WithImplementationAsyncCallbackReturn
    ? Promise<void>
    : undefined;
  mockName(name: string): this;
  mockReturnThis(): this;
  mockReturnValue(value: ReturnType<T>): this;
  mockReturnValueOnce(value: ReturnType<T>): this;
  mockResolvedValue(value: ResolveType<T>): this;
  mockResolvedValueOnce(value: ResolveType<T>): this;
  mockRejectedValue(value: RejectType<T>): this;
  mockRejectedValueOnce(value: RejectType<T>): this;
}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface SpyInstance<T extends FunctionLike = UnknownFunction>
  extends MockInstance<T> {}

type MockFunctionResultIncomplete = {
  type: 'incomplete';
  /**
   * Result of a single call to a mock function that has not yet completed.
   * This occurs if you test the result from within the mock function itself,
   * or from within a function that was called by the mock.
   */
  value: undefined;
};
type MockFunctionResultReturn<T extends FunctionLike = UnknownFunction> = {
  type: 'return';

Review comment (suggestion):
Just an idea. What about function overloads? Isn’t it better pattern in this case? I was trying to play with them briefly and seems like this could help getting rid of `@ts-expect-error`. Or you tried and bump into some issue?

```suggestion
  withImplementation(fn: T, callback: () => void): void;
  withImplementation(fn: T, callback: () => Promise<unknown>): Promise<void>;
```

Code after:

type RejectType<T extends FunctionLike> = ReturnType<T> extends PromiseLike<any>
  ? unknown
  : never;

export interface MockInstance<T extends FunctionLike = UnknownFunction> {
  _isMockFunction: true;
  _protoImpl: Function;
  getMockImplementation(): T | undefined;
  getMockName(): string;
  mock: MockFunctionState<T>;
  mockClear(): this;
  mockReset(): this;
  mockRestore(): void;
  mockImplementation(fn: T): this;
  mockImplementationOnce(fn: T): this;
  withImplementation(fn: T, callback: () => Promise<unknown>): Promise<void>;
  withImplementation(fn: T, callback: () => void): void;
  mockName(name: string): this;
  mockReturnThis(): this;
  mockReturnValue(value: ReturnType<T>): this;
  mockReturnValueOnce(value: ReturnType<T>): this;
  mockResolvedValue(value: ResolveType<T>): this;
  mockResolvedValueOnce(value: ResolveType<T>): this;
  mockRejectedValue(value: RejectType<T>): this;
  mockRejectedValueOnce(value: RejectType<T>): this;
}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface SpyInstance<T extends FunctionLike = UnknownFunction>
  extends MockInstance<T> {}

type MockFunctionResultIncomplete = {
  type: 'incomplete';
  /**
   * Result of a single call to a mock function that has not yet completed.
   * This occurs if you test the result from within the mock function itself,
   * or from within a function that was called by the mock.
   */
  value: undefined;
};
type MockFunctionResultReturn<T extends FunctionLike = UnknownFunction> = {
  type: 'return';
  /**
   * Result of a single call to a mock function that returned.
   */
  value: ReturnType<T>;
};
type MockFunctionResultThrow = {
  type: 'throw';
  /**