Repository navigation
Description
🔎 Search Terms
TS2719 distributive, TS2719 conditional type, TS2719 generic signature, "Two different types with this name exist" conditional, "has been distributed here", distributed type parameter, "non-distributed", distributive conditional identical signature, 64237, 64307
🕗 Version & Regression Information
- This changed in commit or PR Distinguish between non-distributed and distributed type parameters #64237: tsc 6.0.3 accepts the code; tsgo built from
mainat d61a7d2 reports TS2719. - PR Normalize distributed type parameters in conditional type relationships #64307 fixes it. I built its head and the error goes away. The PR has no linked issue, so this is that issue.
⏯ Playground Link
💻 Code
// --strict
declare let f: <A>(m: A, r: (a: A extends string ? A : 0) => void) => void;
export let g: <A>(m: A, r: (a: A extends string ? A : 0) => void) => void = f;🙁 Actual behavior
main.ts(2,12): error TS2719: Type '<A>(m: A, r: (a: A extends string ? A : 0) => void) => void' is not assignable to type '<A>(m: A, r: (a: A extends string ? A : 0) => void) => void'. Two different types with this name exist, but they are unrelated.
Types of parameters 'r' and 'r' are incompatible.
Types of parameters 'a' and 'a' are incompatible.
Type 'A extends string ? A : 0' is not assignable to type 'A extends string ? A : 0'. Two different types with this name exist, but they are unrelated.
Type '0 | A' is not assignable to type 'A extends string ? A : 0'.
Type '0' is not assignable to type 'A extends string ? A : 0'.
Type 'string & A' is not assignable to type 'A'.
'string & A' is only assignable to the non-distributed 'A', but 'A' has been distributed here.
🙂 Expected behavior
No error: the two signatures are identical. tsc 6.0.3 accepts this.
Additional information about the issue
#64237 gave each type parameter a "distributed" twin, which references inside a distributive conditional type resolve to. When the checker compares a generic signature with an identical one, inference maps the source's distributed parameter to the target's plain parameter, while the target keeps its distributed one. The two identical conditional types then fail to relate.
Mateusz Burzyński (@Andarist)'s #64307 fixes this by instantiating the target side of the comparison too, so both distributed parameters map back to the non-distributed one. The PR is open, and the bot asked for an issue that references it, so I'm filing this one.
microsoft/typescript-go#3488 reported a similar TS2719 between identical conditional types earlier this year. It was closed as fixed in April, and its repro still compiles cleanly on current main, so this is a new regression rather than that bug coming back.
This breaks real code. Compiling the source of redux-toolkit v2 fails at builderCallback(builder) in mapBuilders.ts. There the builder object, whose addMatcher takes a type-predicate matcher plus a reducer typed A extends Action ? A : A & Action, is checked against the ActionReducerMapBuilder.addMatcher declaration with the same reducer type. VS Code's configuration resolver (resolveAsync in src/vs/workbench/services/configurationResolver/common/variableResolver.ts) fails the same way. We're carrying #64307 as a local patch in the meantime.
Activity
fix: make the Exact helper compile on TypeScript 7.1 (#1293)
tim-smart commentedon Nov 2, 2026
Hi! This also affects the Effect typescript library. Below is a report from AI:
Another repro of this regression, in a different shape from the one above: no callback parameter. The conditional comes from the return type of a generic function, instantiated with the caller's own type parameter. This is how library wrappers forward to generic functions, and in Effect it breaks
HttpClient.catchTagand the operation constructors in our GraphQL module.08883da)The elaboration for case 1 ends with
'K' is only assignable to the non-distributed 'K', but 'K' has been distributed here.So #64307 fixes it. As far as I can tell, its new tests all have both conditionals written in the same scope. None of them relates the declared return type of a generic function, instantiated with an outer type parameter, to an identical conditional written by the caller. Case 1 might be worth adding as a regression test.
trackoor commentedon Nov 7, 2026
vuejs/core hits this too:
toHandlerKeyinpackages/shared/src/general.tsfailstsc --noEmit --strict. Reduced:tsc --noEmit --strict repro.ts:Fails: 7.1.0-dev.20260917.1 through 7.1.0-dev.20261106.1, and 7.1.0-beta. Works: 5.9.3, 6.0.3, 7.0.1-rc, 7.0.2, 7.1.0-dev.20260916.1. So 7.0.x is fine and it appeared between the 20260916 and 20260917 nightlies.
#64307 (built at
08883da) fixes it: no errors.Playground (TypeScript Go, 7.1 nightly 2026.11.6): https://tsgo.sxzz.dev/#eNqFT7uOwkAM/BXLugKkKAIKiuWAhp4mXRYpUdig5eGN1uYhRfl3vCB03VGNPDP2jHts0ZQlXmpPuTBm6B5diAJNIBY4GfgtwD3E0Z6BJXo6rEZsoBjDcgV/kkWLsH6DgSrQT18MFSwtwb8XRqxbLzurXTerMdT89fDCEu6yEoW1Z+sP+ZEDafk+5VlswqXzZxe3nXj9w6KBl5K0VKGRREm8uuxDh6tsfEy0xb1nNSRlsDSkqF2GDRrUhJvCbDKb59NpPtf5jqatz+yGJ3XWZQM