Typescript, Как написать типизированный метод flatten для массива - PullRequest
0 голосов
/ 13 марта 2019

Я пытаюсь написать в машинописи что-то похожее на https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat

Однако я хочу иметь возможность сглаживать вложенный список произвольной глубины; а также я хочу ограничить все элементы, не являющиеся массивами, одним типом.

Что-то вроде:

interface NestedList<T> extends Array<T | NestedList<T>> {}

Я до сих пор получил это:

export const flat = <T>(ls: NestedList<T>): T[] => {
   const reducer = (acc: T[], it: T | NestedList<T>): T[] => acc.concat(
      Array.isArray(it) ? it.reduce(reducer, []) : it
   );

   return ls.reduce(reducer, []);
};

Однако вывод типа не работает

   it('works with type inference', () => {
      interface Foo<T> { v: T; }

      const data: { [_: string]: { [_: string]: Foo<number> } } = {
         bar: { x: { v: 1 } },
         moo: { y: { v: 2 }, z: { v: 3 } }
      };

      const nested: Foo<number>[][] = Object.values(data).map(val => Object.values(val));
      const list2: Foo<number>[] = flat(nested);
      expect(list2).toEqual([{ v: 1 }, { v: 2 }, { v: 3 }]);
   });

Получает ошибку типа в этой строке:

const list2: Foo<number>[] = flat(nested);

Ошибка:

Type '(Foo<number>[] | ConcatArray<Foo<number>[]>)[]' is not assignable to type 'Foo<number>[]'.
  Type 'Foo<number>[] | ConcatArray<Foo<number>[]>' is not assignable to type 'Foo<number>'.
    Property 'v' is missing in type 'Foo<number>[]' but required in type 'Foo<number>'

Что мне здесь не хватает? Любая помощь приветствуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...