TypeScript: noImplicitAny checks don't work with arrays if mutated

And duplicate errors should be suppressed.

TypeScript Version: master

Search Terms:

Code

const a = [];
a;
const b = [];
b.push(1);

Expected behavior:

$ node built/local/tsc.js --noEmit index.ts --noImplicitAny
index.ts(1,7): error TS7034: Variable 'a' implicitly has type 'any[]' in some locations where its type cannot be determined.
index.ts(3,7): error TS7034: Variable 'b' implicitly has type 'any[]' in some locations where its type cannot be determined.

Actual behavior:

$ node built/local/tsc.js --noEmit index.ts --noImplicitAny
index.ts(1,7): error TS7034: Variable 'a' implicitly has type 'any[]' in some locations where its type cannot be determined.
index.ts(2,1): error TS7005: Variable 'a' implicitly has an 'any[]' type.

Playground Link:

Related Issues:

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 20 (15 by maintainers)

Most upvoted comments

Then you shouldn’t use such an insufficient type inference in strict mode.

The error happens with only one evolving array if you use it in a way other than direct access:

declare function f(arr: ReadonlyArray<number>): void; // May assign `arr` to something or use it in a closure
const a = [];
a.push(0);
f(a);
a.push("");
// ...run-time error happens later on and is hard to track down...

The error would be detected by freezing the array’s type at the call. It seems rare to write code that relies on arr temporarily having a more specific type than it ends up having, but more common to use an array before all elements have been written. We don’t really need to time-travel and get the final type of a to detect this error, we just need to prevent the type from changing after use.

I found the following case.

const a = [];
const b = [];
b.push(0);
a.push(b);
b.push('');
const c: number[][] = a; // wrong but no error.

BTW, can you also take a look at #22046?