microsoft / microsoft/TypeScript

Recursive tuple cannot be computed through generic, but valid in a declarative form

Offen
#62,704 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bug Domain: check: Type Circularity Help Wanted
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
2 T. 4 Std.
Gemergte PRs (30 T.)
132

Beschreibung

🔎 Search Terms

ts2589 "Type instantiation is excessively deep and possibly infinite"

🕗 Version & Regression Information
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about ts2589
  • I was unable to test this on prior versions before v4.7.0 because infer T extends R syntax not introduced
⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.9.3#code/C4TwDgpgBAYg9nKBeKBvAUFKAbCBDAEwEsA7AcwC4oByPagGkygCcIBnYKgbXjgF1GAXwDc6dKEhQAogA8weEgQA8AFQB8yKCqgQZwCIrZomWXIVKUopAGYRmUADKisWVhyo27UAEo69BgiMFEC4+dEEoAH4oLgd6KAA6JNl5RQBZYKVvNT4oKhIIADc7UXFwaBSFAgySEFU-fUMoYNCNJBMtBoCjLk97GCJmDnikhL6fdmBc6K5KxSUBoeA1EeS5Kpq670mcvJi+UoloFUmAQU055V41UQB6W5dHx4A9AD8tcqsSDgVgIjw-nASFYjLoAMbsNhEYrYEBQAgQCBgZqKKBgOBsKEAI1hX2spCI+gSAAoAEwAVgAHABOACUYiOWkmACFNFxaAwmRxmQd0EA

💻 Code
type Foo = {
  leading: 'a',
  rest: [Foo],
};

type Expand<T> = T extends {
    leading: infer L;
    rest: infer R extends any[]
} ? [L, ...ExpandMany<R>] : never;

type ExpandMany<T extends any[]> =
    T extends [infer First, ...infer Rest] ? [Expand<First>, ...ExpandMany<Rest>] : [];

type TestA = Expand<Foo>;
//           ^~ Type instantiation is excessively deep and possibly infinite.(2589)

type TestB = ['a', TestB];
🙁 Actual behavior

TestA meant to be:

TestA
-> Expand<Foo>
-> ['a', ...ExpandMany<[Foo]>]
-> ['a', ...[Expand<Foo>]]
-> ['a', Expand<Foo>]
-> ['a', TestA]

which is identical to TestB but TS complains the instantiation cannot stop.

🙂 Expected behavior

Stop expansion at first reference at appeared structure Expand<Foo>, that is:

type TestA = Expand<Foo>;
//      ^?~ type TestA = ['a', Expand<Foo>]
// or more intelligent `type TestA = ['a', TestA]`
Additional information about the issue

This code is useful when Foo is as const inferred from a runtime constant, and we want a tuple-like typing calculated from Foo. Since TypeScript support self-referential tuple by declarative just like TestB, it would be better for support that in a computed way like Expand<Foo>.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit dem verlinkten TypeScript Playground-Beispiel und bestätige den TS2589-Fehler für TestA, während TestB akzeptiert wird. Verfolge, wie rekursive bedingte und Tupeltypen instanziiert werden, und definiere die Behebung anschließend so, dass die berechnete Form sich bei einem selbstreferenziellen Tupel stabilisieren darf, ohne Rückschritte bei der Rekursionsdiagnostik.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers
Issue-Typ
Bug
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.