microsoft / microsoft/TypeScript
Regression of `this is` type predicate for intersection of unions from 4.7 to 4.8
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Go
- Sterne
- 111k
- Forks
- 14.3k
- Ø Merge
- 2 T. 4 Std.
- Gemergte PRs (30 T.)
- 132
Beschreibung
🔎 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.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne mit dem verlinkten TypeScript Playground und vergleiche die Reproduktion in 4.7.4 und 4.8.4. Verfolge die von Context.check() durchgeführte Eingrenzung für das Beispiel FilterContext<Context, "one" | "two">. Als erledigt gilt, dass der Zugriff auf breaks akzeptiert und als number inferiert wird und die Regression durch einen Test abgedeckt ist.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- typescript
- Bereich
- compilers
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Ruhig
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 38/100