google / google/closure-compiler
Compiler loses type narrowing info within nested functions
- 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
Assessment
This issue has not been assessed yet.