microsoft / microsoft/TypeScript

Bug: null can be excluded by !== null in flow before typeof === 'object', but not excluded by predicate function.

Offen
#60,102 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Domain: check: Control Flow Help Wanted Possible Improvement
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
1 T. 19 Std.
Gemergte PRs (30 T.)
117

Beschreibung

🔎 Search Terms

"null", "control flow", "narrowing", "narrow", "exclusion", "object", "typeof"

🕗 Version & Regression Information

Potentially, we could expect the behaviors of if (a === null) and if ((v => v !== null)(a)) (inferred as predicate since TS 5.5) should be the same, but it's actually not in specific cases.

If it's combined with typeof a === 'object' check in the same flow, first one is correctly omits the null possibility, while second one doesn't.

image

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.6.2#code/MYewdgzgLgBAlhAcgVwDapgXhgCgG4BcMyYA1mCAO5gCUWAfDHlptmGqgNwBQA9LzEEwAegH5uoSLABmWXAEMiJclVoMYAb25D4snAhToc8mnQBOAUyjIzYHjrh6oATwAOFkLPkwAhKxgA5CAARgBWFsBQAeZWNnbaQvL2-CLiAL483BLg0DAA5nLGSmQU1HSYjFoOet6sbBwx1rb2Qo64Lu6eMN5+2EFhEVGNcS2CSdopYtwZQA

💻 Code
const isNull = (v: unknown) => v === null;
//    ^?
const f = (a: unknown) => {
    if (isNull(a)) return;
    if (typeof a !== 'object') return;
    a;
 // ^?
};


const g = (a: unknown) => {
    if (a === null) return;
    if (typeof a !== 'object') return;
    a;
 // ^?
};
🙁 Actual behavior

Last a in f is inferred as object | null.

🙂 Expected behavior

Last a in f would be inferred as object.

Additional information about the issue

Here is important to check typeof === 'object' after the check for null, because type narrowing step is formally, unknownobject | nullobject. === null alone cannot narrow anything on unknown.

If you swap the if-statements in above, you can see both is inferred as object.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit den TypeScript Playground-Links und den minimalen Reproduktionen für f und g und vergleiche die abgeleiteten Typen nach der typeof-Prüfung. Verfolge die Control-Flow-Narrowing- und das Verhalten des abgeleiteten Prädikats, die für den Unterschied verantwortlich sind; als erledigt gilt die Aufgabe, wenn der Prädikatsfall a auf object ohne null eingrenzt und eine Regression-Abdeckung für das gemeldete Beispiel vorhanden 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
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.