You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Type parameter escapes its constraint in a recursive call resolution #64529
interfaceSchema<O>{readonlyout: O}typeShape=Record<string,Schema<any>>;typeLookup={x: 1;dflt: 2};declarefunctionobject<SextendsShape,PextendskeyofLookup>(shape: S): Schema<{[KinkeyofS]: S[K]["out"]}>&{p: P;f: (x: P)=>void};declareconststr: Schema<string>;constu=object({name: str})satisfies{p: number|"x"};u.f(42);// error, P is "x"constt=object({name: str,getrec(){returnobject({inner: t});}})satisfies{p: number|"x"};t.f(42);// no errorconsttp: "x"=t.p;// error: Type 'number | "x"' is not assignable to type '"x"'
🙁 Actual behavior
P on t is number | "x", outside keyof Lookup, with no diagnostic. P only has a return-type inference from satisfies. The outer resolution filters it by the constraint, the re-entrant one doesn't, and typeof t ends up with the re-entrant result. With two mutually recursive consts only the one that resolves first gets the leaked type, so swapping the declaration order moves the error. Wes raised this in review: #64311 (review)
🙂 Expected behavior
P is "x" on t as it is on u, and t.f(42) is an error.
Activity