microsoft / microsoft/TypeScript

Regression of `this is` type predicate for intersection of unions from 4.7 to 4.8

オープン
#63,039 コメント 4 件 リアクション 1 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Bug Domain: This-Typing Needs Human Review
主要言語
Go
スター
111k
フォーク
14.3k
平均マージ
2日 4時間
マージ済み PR(30日)
132

説明

### 🔎 Search Terms

"this is" "type predicate" "intersection" "union"

### 🕗 Version & Regression Information

- This changed between versions 4.7.4 and 4.8.4

### ⏯ Playground Link

https://www.typescriptlang.org/play/?ssl=40&ssc=1&pln=1&pc=1#code/PTAEF5NBlBRAVAqgBQFABcCeAHApqRbAEwEN19xQBvUAV2LNwH0BLIgLlADtaBbAI1wAnUAF8A3KgDGAGxIBneaADCAey7kAHumqpQ+0FPXz0Q2lPSqhACmy1+MllLoNynQqXIBKaqL0GpAAtcKQBray9OdECWJViVYLDcIl0DNNAhXHRaIS5QU1pcSTS-Pyw8BJDQ5IhqF09cThoAJVgAWQB5ADVYJngACQBJaD6OpgAxQYANAH5OLlwAN2ExMUlUEAgoeABNZFhQNoBBAHFB5QwcfHGWGXIhNQ1cbQAeZVBn8i4iJUetdAANKAAIofbS4b5KExCFhcADmAD5ashhAAzKy8YGFISYF7+fTKAH40DNWhcLHCXHAhGoBGSTYkbDYGSYUAkUAAR2xrMy8lod1A-FZsPu8hC6FhcNALB0AHcZYECK5cECSN98sE8rCAFbiyXSjSqFSXCoooTooSY7lvMFfH4qdT-IGIW0Q+2qfi6ixIyguz5upRk0JcVSyrjEmYqUAAMjq9Aa7mVMYIYmJ8yWwkk5XwpPJ1tB-shoGhkp9DoEsNwLyOimE6AA0rgqQigdSs1dQDWxUIG02XgXwUWS-CywO7YGuMHQ+G0pHmiErER+0CAHLqFf8uQOKtBkNhhE0tLp5ZCdabIi4VGVtlEIgyljqEgyUBX3Ayd15F3y6KgRZPwqgAABmSF5XgsRCASa+BqBWCwvIgQL1q6Q6mKWtR+oO9q7tOEYprGyAkD2LBPi885GEIS6wJosi0BeLz1kC1SYKoqIEC2dDfJelZEAeabcBmp6oBsYCQJQ-QdAA6qAgzwKAABCrRHPW0CoBesiEfgRhcCYhjoJonA3Hcwh-J8eJpIZ9wma8VmAqAABE6i4HZoAAD72egsqqHZLbEnZHlebSkhaTpnlCKESiUBYmgAHTxowsXKqwRDthUElWOFtTWNmLG6ZoybKIk1REF4ADadlxeQdkALplRVzBsNVkgsKx1hRdFQRVBEPhUMSwU6PwmQkBlkV6QlDRjYwSWSH4QA

### 💻 Code

```ts
// === SETUP
type Update = { update_id: number };
class Context {
constructor(public update: Update) {}
check(): this is Checked {
return true;
}
}
type Checked = { update: { REMOVE_THIS_TO_FIX?: never } };

// === TYPE MAGIC
type FilterContext = PerformQuery<
C,
RunQuery
>;
// apply a query result by intersecting it with Update, and then injecting into C
type PerformQuery = U extends unknown
? C & { update: Update & U }
: never;
type RunQuery = Combine, Q>;
type AssertKey = Q extends unknown
? Record>
: never;

// define additional fields on U with value `undefined`
type Combine = U extends unknown
? U & Partial, undefined>>
: never;

// === HOW IT BREAKS
declare const ctx: FilterContext<
FilterContext,
"two"
>;
const works = ctx.update.update_id;
type Works = (typeof ctx & Checked)["update"]["update_id"];
if (ctx.check()) {
const breaks = ctx.update.update_id;
}
```

### 🙁 Actual behavior

In the line where the variable `breaks` is defined, `ctx.update` is `never`

### 🙂 Expected behavior

The variable `breaks` can be defined and it has type `number`

### Additional information about the issue

If you change a seemingly unrelated piece in the code, the error goes away!
```ts
// Replace
type Checked = { update: { REMOVE_THIS_TO_FIX?: never } };
// by
type Checked = { update: { } };
```
and then everything works as expected.

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

リンクされている TypeScript Playground から始め、4.7.4 と 4.8.4 で再現結果を比較してください。`FilterContext` の例について、`Context.check()` によって行われる絞り込みを追跡してください。`breaks` へのアクセスが受け入れられ、`number` として推論され、回帰がテストでカバーされれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
typescript
領域
compilers
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
静か
明瞭さ
おおむね明確
初心者へのやさしさ
38/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。