microsoft / microsoft/TypeScript

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

Abierto
#63,039 4 comentarios 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Bug Domain: This-Typing Needs Human Review
Lenguaje dominante
Go
Estrellas
111k
Forks
14.3k
Merge medio
2 d 4 h
PR fusionados (30 d)
132

Descripción

🔎 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
// === 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<C extends Context, Q extends string> = PerformQuery<
    C,
    RunQuery<Q>
>;
// apply a query result by intersecting it with Update, and then injecting into C
type PerformQuery<C extends Context, U extends object> = U extends unknown
    ? C & { update: Update & U }
    : never;
type RunQuery<Q extends string> = Combine<AssertKey<Q>, Q>;
type AssertKey<Q extends string> = Q extends unknown
    ? Record<Q, NonNullable<unknown>>
    : never;

// define additional fields on U with value `undefined`
type Combine<U, K extends string> = U extends unknown
    ? U & Partial<Record<Exclude<K, keyof U>, undefined>>
    : never;

// === HOW IT BREAKS
declare const ctx: FilterContext<
    FilterContext<Context, "one" | "two">,
    "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!

// Replace
type Checked = { update: { REMOVE_THIS_TO_FIX?: never } };
// by
type Checked = { update: { } };

and then everything works as expected.

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con el TypeScript Playground enlazado y compara la reproducción en 4.7.4 y 4.8.4. Rastrea el estrechamiento realizado por Context.check() para el ejemplo FilterContext<Context, "one" | "two">. Se considera terminado cuando el acceso a breaks se acepta y se infiere como number, y la regresión queda cubierta por una prueba.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
typescript
Área
compilers
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Tranquilo
Claridad
Bastante claro
Aptitud para principiantes
38/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.