microsoft / microsoft/TypeScript
Regression of `this is` type predicate for intersection of unions from 4.7 to 4.8
Nessuno ha ancora preso questa issue.
- 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
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- 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