microsoft / microsoft/TypeScript
Regression of `this is` type predicate for intersection of unions from 4.7 to 4.8
Nadie ha tomado este issue todavía.
- 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
💻 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
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- 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