Skip to content

Merge interfaces when merging TypeScript code #151

@miorel

Description

@miorel

Some goodies all add methods to the same interface. See below example how map and filter both update Iterator<T> currently. We'd prefer to have a single declaration for Iterator<T> that combines map and filter together.

////////////////////////// BEGIN ADVENTURE PACK CODE ///////////////////////////
// Adventure Pack commit 9bf9e9a538edc5a3b379c903e854bbfae57247a9
// Running at: https://code-chronicles-code.github.io/leetcode-curriculum/

declare global {
  interface FunctionConstructor {
    returnThis<T>(this: T): T;
  }

  interface Iterator<T> {
    toIterable(this: Iterator<T>): IterableIterator<T>;
  }

  interface Iterator<T> {
    filter(
      this: Iterator<T>,
      callbackfn: (value: T, index: number) => unknown,
    ): Generator<T, void, void>;
  }

  interface Iterator<T> {
    map<TOut>(
      this: Iterator<T>,
      callbackFn: (element: T, index: number) => TOut,
    ): Generator<TOut, void, void>;
  }
}

Function.returnThis = function <T>(this: T): T {
  return this;
};

const iteratorPrototype = Object.getPrototypeOf(
  Object.getPrototypeOf([].values()),
) as Iterator<unknown, unknown, unknown>;

iteratorPrototype.toIterable = function <T>(
  this: Iterator<T>,
): IterableIterator<T> {
  (this as unknown as Record<symbol, unknown>)[Symbol.iterator] ??=
    Function.returnThis;
  return this as unknown as IterableIterator<T>;
};

iteratorPrototype.filter ??= function* <T>(
  this: Iterator<T>,
  callbackFn: (element: T, index: number) => unknown,
): Generator<T, void, void> {
  let index = 0;
  for (const element of this.toIterable()) {
    if (callbackFn(element, index)) {
      yield element;
    }
    ++index;
  }
};

iteratorPrototype.map ??= function* <TIn, TOut>(
  this: Iterator<TIn>,
  callbackFn: (element: TIn, index: number) => TOut,
): Generator<TOut, void, void> {
  let index = 0;
  for (const element of this.toIterable()) {
    yield callbackFn(element, index);
    ++index;
  }
};

/////////////////////////// END ADVENTURE PACK CODE ////////////////////////////

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requesttypescriptAdventure Pack TypeScript issue

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions