Skip to content

TS2719 "Two different types with this name exist" between identical generic signatures with a distributive conditional parameter type (regression from #64237) #64673

Open

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

⏯ Playground Link

https://tsgo.sxzz.dev/#eNqlk91u2zAMhV/lQAOWFnDdLC0a1F07BNguNqDo0PUuDhDFph1timRIcn5Q9N1HxUnarZe5sWmS+kgeys+iEtl4LBZSmTR4kYjzc5yd+eBUEVJMqymkKTGtp5jLJUGVZIIqpEbYNOQTeAvpvaqNMjWsIQSLMCdYfrjcMM3PbatLSL2SG4+VdX/S6N/Gvq0bKgKVOAm+wFXaTy9OMxgLcs6617xREVquyVm15ZrKFIQPV5eDi+ENKrVmwGyDn4/Rd9EfnmbbQ+goePo1GH66zvDEHaP3eXR3ssgwSuAynEi2QOtApvSIU/MUX9iVoX+K2zssrSoPRm+HVZ5bDLu55Ux3Qx9NT3f4p5VFqaqKHGvd6YyVCnPWNVaWC2Km8iHBrA1R7A2kI7TGkZYs5p4DpOmr3dvV/4hRL05gjd78PwLvzVhzVqqYy3DWtTfqJQdGrMcOvgoeMyKDt5m8b+JyuSmp0LEhTQFVhiMkuckNrRvrwpZVH8XCLSrmiUkyFnzZrKlUnf721vCdf84NkIvCLhqlyT00QVnjc5FhG4mxIF1NIbpyQZ7bYjvZBxe2bDV1wcaRJ7ekd+FH8la3kdwlzlpTcrE3ed1fF6PBtXRwk7/fAr6bQM427+K2DV+V66BxIW+I3Srkvug/x1zsZ0k/WIL7Q/8xIya85OZFTCaJKEQmWKElvwb9wVV6nQ4u+XslskpqTy9/AUEAUsk=

💻 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

  1. tim-smart commented on Nov 2, 2026

    @tim-smart

    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.catchTag and the operation constructors in our GraphQL module.

    // --strict
    
    // 1. A generic function's distributive conditional return type,
    //    instantiated with the caller's type parameter.
    declare function f<T>(t: T): T extends string[] ? T[number] : T
    export const g = <K>(k: K): K extends string[] ? K[number] : K => f(k)
    
    // 2. Same, but the false branch doesn't mention the check type: passes on 7.1 too.
    declare function f2<T>(t: T): T extends string[] ? T[number] : boolean
    export const g2 = <K>(k: K): K extends string[] ? K[number] : boolean => f2(k)
    
    // 3. The shape it takes in Effect: a wrapper forwarding to a generic `catchTag`,
    //    where the conditional sits inside Exclude.
    type ExcludeTag<E, K> = Exclude<E, { readonly _tag: K }>
    declare function catchTag<E, K>(e: E, k: K): ExcludeTag<E, K extends readonly string[] ? K[number] : K>
    export const wrapper = <E, K>(e: E, k: K): ExcludeTag<E, K extends readonly string[] ? K[number] : K> =>
      catchTag(e, k)
    result
    7.0.2 no errors
    7.1.0-beta TS2719 on 1 and 3
    7.1.0-dev.20261102.1 TS2719 on 1 and 3
    #64307 (built at 08883da) no errors
    repro.ts(4,67): error TS2719: Type 'K extends string[] ? K[number] : K' is not assignable to type 'K extends string[] ? K[number] : K'. Two different types with this name exist, but they are unrelated.
    repro.ts(15,3): error TS2719: Type 'Exclude<E, { readonly _tag: K extends readonly string[] ? K[number] : K; }>' is not assignable to type 'Exclude<E, { readonly _tag: K extends readonly string[] ? K[number] : K; }>'. Two different types with this name exist, but they are unrelated.
    

    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.

  2. trackoor commented on Nov 7, 2026

    @trackoor

    vuejs/core hits this too: toHandlerKey in packages/shared/src/general.ts fails tsc --noEmit --strict. Reduced:

    export const k: <T extends string>(s: T) => T extends "" ? "" : `on${T}` =
      <T extends string>(s: T) => (s ? `on${s}` : ``) as T extends "" ? "" : `on${T}`;

    tsc --noEmit --strict repro.ts:

    repro.ts(1,14): error TS2719: Type '<T extends string>(s: T) => T extends "" ? "" : `on${T}`' is not assignable to type '<T extends string>(s: T) => T extends "" ? "" : `on${T}`'. Two different types with this name exist, but they are unrelated.
      Type 'T extends "" ? "" : `on${T}`' is not assignable to type 'T extends "" ? "" : `on${T}`'. Two different types with this name exist, but they are unrelated.
        Type '"" | `on${T}`' is not assignable to type 'T extends "" ? "" : `on${T}`'.
          Type '""' is not assignable to type 'T extends "" ? "" : `on${T}`'.
            Type '`on${T}`' is not assignable to type '`on${T}`'. Two different types with this name exist, but they are unrelated.
    

    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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Needs InvestigationThis issue needs a team member to investigate its status.

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions