Skip to content

Narrowing does not work when done via a predicate that narrows via mapped typesΒ #47283

Closed
@devanshj

Description

@devanshj

Bug Report

πŸ”Ž Search Terms

Type predicate, mapped types, narrowing

πŸ•— Version & Regression Information

Tried with v4.3.5

⏯ Playground Link

Playground link

πŸ’» Code

declare const areValuesDefined:
  <T>(t: T) => t is { [K in keyof T]: Exclude<T[K], undefined> }

let x = {} as { a: string | undefined } | { b: string }
if (areValuesDefined(x)) {
  x;
  // Expected: { a: string } | { b: string }
  // Actual: { b: string }
}

πŸ™ Actual behavior

The type of x, inside the if block, is { b: string }

πŸ™‚ Expected behavior

The type of x, inside the if block, should have been { a: string } | { b: string }.

Also the quickinfo of areValueDefined is inconsistent with the what actually the narrowed type is. The quickinfo shows the expected type.

Also the narrowing { b: string } is particularly weird, even if it somehow failed it should have kept the type as it is.

And the narrowing does work in this case...

declare const areValuesDefined:
  <T>(t: T) => t is { [K in keyof T]: Exclude<T[K], undefined> }

let x = {} as { a: string | undefined } | { b: string | undefined }
if (areValuesDefined(x)) {
  x;
  // Expected: { a: string } | { b: string }
  // Actual: { a: string } | { b: string }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions