So I was answering this question just now, and in it I found something strange that I could not find explanations of.
If we have a generic function, and the parameter is optional and the parameter's type is using the generic, something like this:
function ok<T>(thing?: T) {
}
Then when we try to narrow thing inside the function to just T explicitly checking if it is undefined:
thing !== undefined ? thing : 0;
// ^? T & ({} | null)
Then thing is narrowed to T & ({} | null). Moreover, when we use typeof, this is narrowed to the expected T. This also behaves the same with if statements.
typeof thing !== "undefined" ? thing : 0;
// ^? T
Here's a minimal reproducible example with all the things I mentioned:
function ok<T>(thing?: T) {
thing !== undefined ? thing : 0;
// ^?
if (thing !== undefined) {
thing
// ^?
}
typeof thing !== "undefined" ? thing : 0;
// ^?
if (typeof thing !== "undefined") {
thing
// ^?
}
}
Why is this the case? Do the two conditions actually have different behavior that I didn't know about? Is this a bug? I'm looking for an explanation for this behavior.