Skip to content

[4.3, 4.4] Inline filtering mapped type conditional with infer fails #46020

Closed

Description

Bug Report

As of TypeScript 4.3, when inlining a mapped type on the left-hand side of extends in a conditional type, TypeScript incorrectly evaluates the condition when the right-hand side contains another mapped type with infer and renders the false condition. When declaring the mapped type explicitly rather than inline, the ternary is correctly evaluated.

This is pretty hard to cover in words, so please check playground link for reproduction.

The language version can be changed to 4.2 to see it working correctly.

🔎 Search Terms

typescript infer inline mapped type never generic inference

🕗 Version & Regression Information

  • This changed between versions 4.2 and 4.3

⏯ Playground Link

Change TS language to 4.2 to see the code functioning correctly, and 4.3 or 4.4 to see failure.

Playground link with relevant code

💻 Code

type DefinedKeys<T> = {
  [K in keyof T]:
    string extends K ? never :
    number extends K ? never :
  K }

type KnownKeys<T> = DefinedKeys<T> extends {
    [_ in keyof T]: infer U
  }
  ? U
  : never;

// This type is the exact same as `KnownKeys`, but inlines `DefinedKeys<T>` instead of declaring it as a separate type
type FailingKnownKeys<T> = {
  [K in keyof T]:
    string extends K ? never :
    number extends K ? never :
  K } extends {
    [_ in keyof T]: infer U
  }
  ? U
  : never;

interface Flags {
  knownFlag1: boolean
  knownFlag2: boolean
  [x: string]: boolean | null | undefined;
}

type DefinedValidationKeys = DefinedKeys<Flags>
type KnownFlags = KnownKeys<Flags>
type FailingKnownFlags = FailingKnownKeys<Flags>

🙁 Actual behavior

In the above code sample, the type FailingKnownFlags is never (the false branch of the ternary of FailingKnownKeys<T>), while KnownFlags correctly is {knownFlag1: boolean, knownFlag2: boolean}

🙂 Expected behavior

KnownKeys<T> === FailingKnownKeys<T>

They are the same declaration, just one being inline and the other with an explicitly extracted type.

Activity

  1. RyanCavanaugh commented on Sep 8, 2026

    @RyanCavanaugh
    Member

    This is a duplicate of #44143. Both examples use the same inline mapped key filter on the left side of extends { [_ in keyof T]: infer U }, which causes the inferred result to become never after TypeScript 4.3.

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

Metadata

Metadata

Labels

BugA bug in TypeScriptDomain: Conditional TypesThe issue relates to conditional typesNeeds InvestigationThis issue needs a team member to investigate its status.RescheduledThis issue was previously scheduled to an earlier milestone

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions