7.1 regression: comparing a recursive `-?` mapped type is quadratic in the number of properties and hits TS2589 (since typescript-go#4820)
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 48/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- go, typescript
- Ambito
- compilers, performance
Direzione di ricerca
Start by reading the variance computation change in microsoft/typescript-go#4820, then reproduce the issue with the supplied one-file repro and tsc -p . --singleThreaded --extendedDiagnostics. Compare instantiation counts for the last good and first bad builds, focusing on the recursive Builder interface, its -? mapped type, and changing S | K argument. Done means the comparison stays near linear in property count and the 500-property repro succeeds without TS2589.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
🔎 Search Terms
variance, TS2589, excessively deep, instantiation count, mapped type, -?, quadratic, 7.1 regression
🕗 Version & Regression Information
- Last good:
7.1.0-dev.20260805.1(gitHead 12318e599d) - First bad:
7.1.0-dev.20260806.1(gitHead 86cc4767d4) - That range is one commit: microsoft/typescript-go#4820, "Order variance computation by associated type symbol".
- Still failing on
7.1.0-betaand7.1.0-dev.20261024.1. - 7.0.2 accepts the code.
Same commit as #64891 and #64930, but this one is about performance: the comparison finishes with a correct result
for small types, it just costs quadratically more instantiations, and on real types it hits the 5M cap.
⏯ Playground Link
The 7.1 builds aren't available in the Playground. CLI repro: one file in an empty directory, tsc -p . --singleThreaded --extendedDiagnostics.
tsconfig.json
{ "compilerOptions": { "strict": true, "noEmit": true, "types": [] }, "files": ["repro.ts"] }
💻 Code
type D = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
type Entity = Record<`f${'0' | '1' | '2' | '3' | '4'}${D}${D}`, string> // 500 properties
interface Method<T, K extends keyof T, S> {
(): Builder<T, S | K>
}
type Builder<T, S = never> = { [K in keyof T]-?: Method<T, K, S> }
declare const builder: Builder<Entity>
export const widened: Builder<Entity & object> = builder
🙁 Actual behavior
repro.ts(10,14): error TS2589: Type instantiation is excessively deep and possibly infinite.
Instantiations: 5003892 Check time: 79 s
🙂 Expected behavior
No error, as in 7.0.2 and 7.1.0-dev.20260805.1: about 9k instantiations, 0.04 s check time.
Additional information about the issue
With 100 properties (Record<`f${D}${D}`, string>) there is no error, but the count goes from 5,105 to 256,939
instantiations. It grows with the square of the property count: about 66k at 50 properties, 1M at 200 and the 5M cap
near 460.
| build | 100 props: instantiations | 500 props |
|---|---|---|
| 7.0.2 | 5,105 | 9,105, ok |
7.1.0-dev.20260805.1 (12318e599d) |
5,105 | 9,105, ok |
7.1.0-dev.20260806.1 (86cc4767d4) |
256,939 | TS2589 |
| 7.1.0-dev.20261024.1 | 258,143 | TS2589 |
All three of these are needed for the quadratic count; removing any one brings it back to linear:
- the
-?modifier on the homomorphic mapped type; Methodas a generic interface that referencesBuilderagain (with an inline() => Builder<T, S | K>both
7.0.2 and 7.1 are quadratic, so the regression is in how the interface's variance gets computed);- a type argument that actually changes, here
S | K(withBuilder<T, S>it stays linear).
The target also has to be a different but equivalent instantiation (Entity & object); a structurally identical
mapped copy of Entity does not trigger it.
Real-world impact: this is a reduced form of a fluent "selection builder" type from our library, whose
entity types resolve through UnionToIntersection<E> & object, so every selector is compared against
Builder<E & object>. On a ~2,100-file app under 7.1:
- TS2589 appears on ordinary selector call sites, and the callbacks' destructured parameters cascade into TS7031/TS7006.
- The depth error leaves the checker's caches in a bad state, so a later file that checks cleanly on its own reports
TS2339 (members missing on the builder's result type). The error count depends on--checkersand on which files
share a checker (0 to 77). - The project checks
--singleThreadedin 25 s / 2.6 GB on7.1.0-dev.20260805.1; on7.1.0-dev.20260930.4the
same run was OOM-killed at an 18 GB cap, and with default checkers it reached 24 GB before being killed.
- Lingua principale
- Go
- Stelle
- 112k
- Fork
- 15.4k
- Merge medio
- 3g 1h
- PR unite (30g)
- 136
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di microsoft/TypeScript
-
Won't Fix
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
microsoft/TypeScript#65107 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Native API: formatDiagnosticsWithColorAndContext drops related information without a file locationForse già presa @timurzvural l’ha presa 1 giorno fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
microsoft/TypeScript#65087 ·
I maintainer di solito rispondono entro 1 giorno
-
TS7 LSP: documentHighlight returns nothing when the file path contains '@'Forse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. ApertaBug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
microsoft/TypeScript#64758 ·
I maintainer di solito rispondono entro 1 giorno
-
Language server (tsc --lsp) exits with code 1 after `shutdown` and `exit`Forse già presa @rajnish-verma-22172 l’ha presa 13 giorni fa. ApertaBug
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
microsoft/TypeScript#64742 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Class names `eval` and `arguments` are not reported as invalid strict mode bindingsForse già presa @dmety l’ha presa 26 giorni fa. ApertaBug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
microsoft/TypeScript#64661 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di microsoft/TypeScript
Issue simili
-
area: frontend priority: normal
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
TestAutonomousStop_ReportsObservedState fails under host load: 1s wall-clock ceiling vs 250ms cycleApertatype:bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
nightgauge/nightgauge#2909 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
jasonfen/terminal-space-program#842 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
MustacheCase/zanadir#521 ·
I maintainer di solito rispondono entro 1 giorno
-
v3.1.0: spread placement groups fail — label key uses the reserved hetzner.cloud prefixForse già presa @ScrimReaper l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 86/100
stubbi/karpenter-provider-hetzner#120 ·
I maintainer di solito rispondono entro 4 giorni