microsoft / microsoft/TypeScript

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

Aperta
#63,039 4 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Bug Domain: This-Typing Needs Human Review
Lingua principale
Go
Stelle
111k
Fork
14.3k
Merge medio
2g 4h
PR unite (30g)
132

Descrizione

### 🔎 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.

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia dal TypeScript Playground collegato e confronta la riproduzione con 4.7.4 e 4.8.4. Traccia il restringimento eseguito da `Context.check()` per l'esempio `FilterContext`. Il lavoro è completato quando l'accesso a `breaks` viene accettato e inferito come `number`, con la regressione coperta da un test.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
typescript
Ambito
compilers
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Abbastanza chiara
Idoneità per principianti
38/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.