Microsoft/TypeScript

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

Open

#60.102 geöffnet am 30. Sept. 2024

Auf GitHub ansehen
 (0 Kommentare) (0 Reaktionen) (0 zugewiesene Personen)TypeScript (6.726 Forks)batch import
Domain: check: Control FlowHelp WantedPossible Improvement

Repository-Metriken

Stars
 (48.455 Stars)
PR-Merge-Metriken
 (Durchschn. Merge 6T 17h) (9 gemergte PRs in 30 T)

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.

⏯ 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.

Contributor Guide