Skip to content

Narrowing by type predicate fails to produce intersection type with weak typeΒ #58518

@danvk

Description

@danvk

πŸ”Ž Search Terms

  • predicate
  • intersection
  • weak

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.5.0-beta&ssl=7&ssc=20&pln=7&pc=21#code/JYOwLgpgTgZghgYwgAgILIN4ChnIDZwBGEeA-AFzIDOYUoA5gNw7JwXW0OO4D0PyAWzgBrFFAgBHAK7BxAE2RgA9shLABoOJFVQoSqFgC+WLKEixEKAEKYWBYmUo06IJr37iBSgG4oqACzh5ZAAHPRDoMABPRRU1DRAtFGg9A1xCSkIlJTwIOBBmYywYKRAEMGAlEGRgKisACjB-BkolQgArCHKASkomhhqqZBtsXHEwKShqgHJCaZrq-tdCkxKyiqrFCBpG5tdKVG7bXCX6ADo4bmQ+ZCVhFmAYZHrahtPuo9HcRT3zy-cdKlSCxjMYgA

πŸ’» Code

interface A {
  label?: string;
  a?: string;  // make required to eliminate error
}

interface B {
  label?: string;  // remove shared property to eliminate error
  b: boolean;
}

function isB(thing: object): thing is B {
  return 'b' in thing;
}

function test(thing: A) {
  thing.a;  // ok
  if (isB(thing)) {
    thing.a;  // error?
  }
}

πŸ™ Actual behavior

The type of thing inside the conditional is B.

πŸ™‚ Expected behavior

The type of thing inside the conditional should be A & B.

Additional information about the issue

This only happens if:

  1. A is a "weak" type (all optional properties).
  2. A and B have at least one overlapping property.

If either of these isn't the case, then you get the expected intersection type:
image

This came up in vscode while testing #58495 (comment). The issue is there already but is latent because control flow analysis can't see that a type predicate becomes a type assertion without that PR.

https://github.com/microsoft/vscode/blob/273d65a156865def7869e2899235ea2ab9837a81/src/vs/workbench/api/common/extHostTreeViews.ts#L821

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptHelp WantedYou can do this

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions