google / google/closure-compiler

Compiler loses type narrowing info within nested functions

Open
#2,193 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
7.7k
Forks
1.2k
Avg merge
2d 12h
Merged PRs (30d)
6

Description

The following example:

```javascript
const /** number|undefined */ num = 2;
if (num) {
const /** number */ correct = num;
const f = () => {
const /** number */ unexpectedWarning = num;
};
}
```

Produces the following warning:
```
input0:5: WARNING - initializing variable
found : (number|undefined)
required: number
const /** number */ unexpectedWarning = num;
^^^

0 error(s), 1 warning(s), 100.0% typed
```

I can understand why that warning may happen for `var` or `let` (the value of the variable could change before the function is called) but it seems like it should be smarter about dealing with `const`.

This example with default parameters has the same issue:

```javascript
/** @param {number=} num */
function f(num = 2) {
const /** number */ correct = num;
const func = () => {
const /** number */ unexpectedWarning = num;
};
}
```

In this case, I suppose there isn't much that can be done as it would be legal to later write: `num = undefined;`. Maybe the compiler could check for modifications to the parameter value? Seems hard though.

In this case, if default parameter values are used, it seems like the parameter type should always be `number` rather than `number|undefined`. i.e., this would be illegal:

```javascript
/** @param {number=} num */
function f(num = undefined) {}
```

You'd need to write:

```javascript
/** @param {(number|undefined)=} num */
function f(num = undefined) {}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.