Bug Report
π Search Terms
type narrowing, callback
π Version & Regression Information
This is the behavior in every version I tried, and I reviewed the FAQ for entries about type guards.
β― Playground Link
Playground link with relevant code
π» Code
type Option = { isSome: true, value: unknown } | { isSome: false };
export default (
foo: Option,
bar: { baz: Option },
qux: (arg: unknown) => unknown
) => {
if (foo.isSome) {
foo.value;
qux(foo.value);
[].map((_) => foo.value);
}
if (bar.baz.isSome) {
bar.baz.value;
qux(bar.baz.value);
[].map((_) => bar.baz.value);
}
};
π Actual behavior
The line [].map((_) => bar.baz.value); does not compile, inferring bar.baz to be of type Option. I thought it was narrowed down to { isSome: true, value: unknown } just like the above two lines.
π Expected behavior
The aforementioned line should compile as I explained in the last section.
The closest documentation to the situation of my problem is this issue template, which says:
narrowings are not respected in callbacks. In other words:
function fn(obj: { name: string | number }) {
if (typeof obj.name === "string") {
// Errors
window.setTimeout(() => console.log(obj.name.toLowerCase());
}
}
This is intentional since the value of obj.name "could" change types between when the narrowing occurred and when the callback was invoke [sic].
This might make sense, but does not seem to explain why [].map((_) => foo.value); compiles. I don't see why foo.value and bar.baz.value in callbacks produce different results, so I opened this issue.
Bug Report
π Search Terms
type narrowing, callback
π Version & Regression Information
This is the behavior in every version I tried, and I reviewed the FAQ for entries about type guards.
β― Playground Link
Playground link with relevant code
π» Code
π Actual behavior
The line
[].map((_) => bar.baz.value);does not compile, inferringbar.bazto be of typeOption. I thought it was narrowed down to{ isSome: true, value: unknown }just like the above two lines.π Expected behavior
The aforementioned line should compile as I explained in the last section.
The closest documentation to the situation of my problem is this issue template, which says:
This might make sense, but does not seem to explain why
[].map((_) => foo.value);compiles. I don't see whyfoo.valueandbar.baz.valuein callbacks produce different results, so I opened this issue.