Repository navigation
7.1 regression: circular type alias accepts an assignment it should reject (opposite of #64891) #64930
Description
Search Terms
circular type alias variance, missing TS2322, unrelated type arguments assignable, 7.1 regression, #64891
Version & Regression Information
- This changed between versions 7.0.2 and 7.1.0-dev.20261022.1
- This changed in commit or PR Order variance computation by associated type symbol typescript-go#4820
I bisected it with the nightlies: 7.1.0-dev.20260805.1 (built from 12318e599) reports the error, and 7.1.0-dev.20260806.1 (built from 86cc4767d, the #4820 merge) doesn't.
Playground Link
No response
Code
type Params<T, K> = { config: Config<T, K> };
type Handler<T, K> = (params: Params<T, K>) => void;
type Config<T, K> = { read: (item: T) => void; handler: Handler<T, K> };
declare const a: Handler<string, string>;
export const b: Handler<number, string> = a; // should be TS2322{ "compilerOptions": { "strict": true, "noEmit": true, "types": [] }, "files": ["a.ts"] }Actual behavior
No errors. A handler that reads strings is accepted where one that reads numbers is expected.
It's not just close types either: Handler<boolean, { x: 1 }> is accepted too.
Expected behavior
TS2322 on the last line, same as 6.0.3 and 7.0.2.
Additional information about the issue
Hi there!
Some context on how I found this: I've been testing out the latest 7.1 nightlies and I'm super excited about them, mainly for the memory and CPU speedups. We have a very large TypeScript monorepo in production, so those gains make a real difference for us.
While digging into #64891 I found the opposite case, and I think it's the other half of the same bug. That issue is about 7.1 rejecting code it should accept. This one is the opposite, it accepts code it should reject, which is a bit scarier because nothing tells you it happened.
Here's what I see with tsc -p . (same result on every run):
| Build | This repro | #64891 repro |
|---|---|---|
| 6.0.3 | TS2322 (correct) | no errors (correct) |
| 7.0.2 | TS2322 (correct) | no errors (correct) |
| 7.1.0-dev.20261022.1 | no errors (wrong) | TS2322 (wrong) |
| #64893 (6e72aa7, built locally) | TS2322 (correct) | no errors (correct) |
A few other things I noticed while narrowing it down:
-
It needs two type parameters. With only
T, every build reports the error. -
If I move
HandleraboveParams, the nightly reports the error again. -
fix(checker): resolve TS2322 regression in circular generic interface variance calculation #64893 fixes both repros, but the result still depends on what gets checked first. If
Paramsis compared beforeHandler, every build I tried misses theHandlererror, fix(checker): resolve TS2322 regression in circular generic interface variance calculation #64893 included:declare const p: Params<string, string>; export const q: Params<number, string> = p; // TS2322 everywhere declare const a: Handler<string, string>; export const b: Handler<number, string> = a; // missed everywhere
So I'm not sure fix(checker): resolve TS2322 regression in circular generic interface variance calculation #64893 is the full fix, but it does get things back to how 7.0.2 behaves.
Thanks for all the work on 7.x, it's been great so far!
Activity