🔎 Search Terms
"narrowing", "mutation", "shared", "control flow analysis", "have no overlap", "has no overlap"
🕗 Version & Regression Information
This is the behavior in every version I tried, and I reviewed the FAQ for entries about narrowing.
⏯ Playground Link
https://www.typescriptlang.org/play/?ts=5.8.0-dev.20250205#code/MYewdgzgLgBATgVzDAvDAFAMwFwYJSoB8MAbiAJYAmBKxm6eA3AFDMA2AprAIa4DeMXjACMMAD4wATDAC+qGAKGiZLbgDpu8yS0Rh0DIguYwTgjfOEsZTZuUwZ1mlGmEE+x06EghOatiABzdAByAAsONn9gmxkgA
💻 Code
const run = (f: () => void) => f(); // This indirection is necessary to reproduce.
let a: { a: 1 | 2 } = { a: 1 };
a.a = 2;
run(() => {
a.a = 1;
});
// This must be directly in this code flow. For example, two `setTimeout`s where the `if` runs after also does not reproduce the bug.
if (a.a == 1) { // Error: This comparison appears to be unintentional because the types '2' and '1' have no overlap.
console.log('hello');
}
🙁 Actual behavior
On the if (a.a == 1) { line we see the error This comparison appears to be unintentional because the types '2' and '1' have no overlap..
🙂 Expected behavior
Typescript recognises that the value has been captured into another context that could change the value within the old, not-narrowed type, and consequently undoes the narrowing, i.e., between the run call and the if statement in the example above, a.a would have the type 1 | 2 again.
Additional information about the issue
No response
🔎 Search Terms
"narrowing", "mutation", "shared", "control flow analysis", "have no overlap", "has no overlap"
🕗 Version & Regression Information
This is the behavior in every version I tried, and I reviewed the FAQ for entries about narrowing.
⏯ Playground Link
https://www.typescriptlang.org/play/?ts=5.8.0-dev.20250205#code/MYewdgzgLgBATgVzDAvDAFAMwFwYJSoB8MAbiAJYAmBKxm6eA3AFDMA2AprAIa4DeMXjACMMAD4wATDAC+qGAKGiZLbgDpu8yS0Rh0DIguYwTgjfOEsZTZuUwZ1mlGmEE+x06EghOatiABzdAByAAsONn9gmxkgA
💻 Code
🙁 Actual behavior
On the
if (a.a == 1) {line we see the errorThis comparison appears to be unintentional because the types '2' and '1' have no overlap..🙂 Expected behavior
Typescript recognises that the value has been captured into another context that could change the value within the old, not-narrowed type, and consequently undoes the narrowing, i.e., between the
runcall and theifstatement in the example above,a.awould have the type1 | 2again.Additional information about the issue
No response