microsoft / microsoft/TypeScript
Regression of `this is` type predicate for intersection of unions from 4.7 to 4.8
Personne n'a encore pris cette issue.
- Langage dominant
- Go
- Étoiles
- 111k
- Forks
- 14.3k
- Merge moyen
- 2 j 4 h
- PR mergées (30 j)
- 132
Description
🔎 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.
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par le TypeScript Playground lié et comparez la reproduction sur 4.7.4 et 4.8.4. Suivez la réduction effectuée par Context.check() pour l’exemple FilterContext<Context, "one" | "two">. Le travail est terminé lorsque l’accès à breaks est accepté et inféré comme number, et que la régression est couverte par un test.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- typescript
- Domaine
- compilers
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- Calme
- Clarté
- Plutôt claire
- Accessibilité débutants
- 38/100