-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Local variables not narrowed in lambda function bodies #15631
Description
Hello all, love your work with the language. I suspect I may have found a bug:
Local variables that are a union type (such as type | undefined) at declaration aren't being narrowed in lambda functions. Parameters and local aliases of those variables are.
TypeScript Version: 2.2.2 / 2.3.2 / nightly (2.4.0-dev.20170506)
Code
// A *self-contained* demonstration of the problem follows...
// example type
interface Test {
label:string
}
// Function operates without errors, 'parameter' is correctly
// narrowed to Test rather than Test|undefined
function testParameters(parameter:Test|undefined) {
if (parameter) {
console.log(parameter.label);
Promise.resolve().then(() => parameter.label);
}
}
// Local variable is not narrowed in the lambda/arrow
function testLocals(parameter:Test|undefined) {
let local = parameter;
if (local) {
console.log(local.label);
Promise.resolve().then(() => local.label);
//^ Error "Object is possibly 'undefined'."
}
}
// Useful but annoying workaround
function workaround1(parameter:Test|undefined) {
let local = parameter;
if (local) {
let localLabel = local.label;
console.log(local.label);
Promise.resolve().then(() => localLabel);
}
}
// Useful but annoying workaround #2
function workaround2(parameter:Test|undefined) {
let local = parameter;
if (local) {
let localPrime = local;
console.log(local.label);
Promise.resolve().then(() => localPrime.label);
}
}Expected behavior:
I expect union types to be narrowed in lambda functions defined inside of a block with a type guard.
Actual behavior:
Variables that are narrowed in the block a lambda is created are not interpreted as their narrowed type inside the body of the lambda function. The above examples also apply to union types with truthy variables like number | string and their appropriate type guards and to functions written as function(){...}.