Microsoft/TypeScript

Narrowing by type predicate fails to produce intersection type with weak type

Open

#58,518 创建于 2024年5月13日

在 GitHub 查看
 (0 评论) (0 反应) (0 负责人)TypeScript (6,726 fork)batch import
BugDomain: check: Control FlowHelp Wanted

仓库指标

Star
 (48,455 star)
PR 合并指标
 (平均合并 6天 17小时) (30 天内合并 9 个 PR)

描述

🔎 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:

This came up in vscode while testing https://github.com/microsoft/TypeScript/pull/58495#issuecomment-2105358748. 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

贡献者指南