Microsoft/TypeScript

Conditional type eagerly calculated to be invariant breaks referential transparency

Open

#62.798 aperta il 23 nov 2025

Vedi su GitHub
 (4 commenti) (0 reazioni) (0 assegnatari)TypeScript (6726 fork)batch import
BugCursed?Domain: check: Variance RelationshipsHelp Wanted

Metriche repository

Star
 (48.455 star)
Metriche merge PR
 (Merge medio 6g 17h) (9 PR mergiate in 30 g)

Descrizione

🔎 Search Terms

Conditional types, Invariance, Referential transparency

🕗 Version & Regression Information

Tried with v5.9.3

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.9.3#code/C4TwDgpgBAYgPAFQHxQLxQN5QG4EMA2ArhAFxQJQQAewEAdgCYDOUA9gEYBWEAxsFAH4oAawghWAM3JQyFAL4AoBaEhQASgEY0sOBjkpqtRi3hZcZJsABOASzoBzKPsFQARAAtW+Zq5luGrBAsdKz8nt6uCgD0UVBxAHoCSirQMLjapvrK4KnsGbpQ5lCWtg5OSMk56gBMGemG9MyweUIeXj5+rgFBUCFh7ZExcVCJCkA

💻 Code

type F<T> = { value: T extends object ? keyof T : T }

type R1 = F<{}> extends F<{ a: string }> ? "holds" : "does not hold"
//   ^? "does not hold"

type Fa = F<{}>
type Fb = F<{ a: string }>

type R2 = Fa extends Fb ? "holds" : "does not hold"
//   ^? "holds"

🙁 Actual behavior

R1 computes to "does not hold"

🙂 Expected behavior

R1 computes to "holds"

Additional information about the issue

I'm assuming typescript eagerly calculates F to be invariant and then instead of checking the subtype relation on resolved types it calculates subtype relation of the parameters to F. (This would perhaps have made sense if F was explicitly annotated with in out T.)

Guida contributor