microsoft / microsoft/TypeScript

Trying to flatten an array with unknown depth causes a type error

Open
#44,408 3 comments 8 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Needs Investigation
Dominant language
Go
Stars
111k
Forks
14.4k
Avg merge
1d 19h
Merged PRs (30d)
117

Description

Bug Report

Trying to flatten an array with unknown depth causes a type error.

🔎 Search Terms
  • flat
  • Infinity
🕗 Version & Regression Information
  • Errors in version 4.2.4
  • This changed between versions 3.6.2 and 3.7.5 (but probably just because the type definitions aren't supported prior)

The PR https://github.com/microsoft/TypeScript/pull/32131 provides a definition for FlatArray that has this issue.

⏯ Playground Link

Playground link with relevant code

💻 Code
// first define a nested list with arbitrary depth
type Nested<T> = (T | Nested<T>)[];

const arr: Nested<number> = [1,[2,[3]]];

// locally, this bit fails for me (version 4.2.4)
//
// with an error '"recur"' is referenced directly or indirectly in its own type annotation.
const res: number[] = arr.flat(Infinity);

// you can do a quick workaround as follows:
const res2: number[] = (arr as any[]).flat(Infinity);

// but for some reason on the TypeScript playground this doesn't fail, but you can emulate it
// by using the following definition that is equivalent to the one provided in the standard library:
// https://github.com/microsoft/TypeScript/blob/d8e9f6951919a347bb155b938a5006f9efabb778/lib/lib.es2019.array.d.ts#L21
type FlatArray2<Arr, Depth extends number> = {
    "done": Arr,
    "recur": Arr extends ReadonlyArray<infer InnerArr>
        ? FlatArray2<InnerArr, [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20][Depth]>
        : Arr
}[Depth extends -1 ? "done" : "recur"];

// causes a type error: '"recur"' is referenced directly or indirectly in its own type annotation.
type TestFlat<T> = FlatArray2<Nested<T>, typeof Infinity>
🙁 Actual behavior

The code errors with '"recur"' is referenced directly or indirectly in its own type annotation.

🙂 Expected behavior

The code to pass typechecking.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the error with the provided nested-array example and inspect the FlatArray definition in lib/lib.es2019.array.d.ts, along with PR 32131. Determine how unknown-depth flat typing should avoid the recursive type error, then verify that arr.flat(Infinity) passes typechecking without weakening the expected result type.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.