Type Guard Issue with Array.prototype.fill, Array Constructor
See original GitHub issueTypegurd Issue with Array.prototype.fill, Array Constructor
TypeScript Version: 3.5.1
Search Terms:
- Array.prototype.fill
- fill
- ArrayConstructor
- array implicit any
Code
const foo: number[] = new Array(3).fill("foo"); // accepted
Actual behavior:
This code above is accepted because new Array(3)
returns any[]
, and so fill("foo")
returns any[]
.
I know giving type explicitly to Array like
const foo: number[] = new Array<number>(3).fill("foo"); // error
would work, but I believe the compiler should reject the first one. (This is TypeScript.)
Expected behavior:
Option A. Array.prototype.fill returns narrow type
replace declaration of Array.fill
in lib.es2015.core.d.ts
like fill<S extends T>(value: S, start?: number, end?: number): S[];
, then
const foo: number[] = new Array(3).fill("foo");
// error: "Type 'string[]' is not assignable to type 'number[]'."
// because `fill` is resolved as `fill<string>(value: string, .....): string[]`
const bar = new Array(3).fill(0); // `bar` is resolved as `number[]`
bar.fill("bar"); // error: "Type '"bar"' is not assignable to type 'number'."
const baz: (number|string)[] = new Array(3).fill(0); // accepted.
baz.fill("baz"); // accepted.
Option B. Array Constructor never return implicit any
The problem is that Array constructor returns any[]
implicitly. The first code is accepted even with --strict
or any other options. It means we always have to care about “Array constructor returns any[]
”.
Something like #26188 could solve this issue.
Playground Link: https://www.typescriptlang.org/play/#src=const foo%3A number[] %3D new Array(3).fill(“foo”)%3B
Related Issues: #29604
Issue Analytics
- State:
- Created 4 years ago
- Reactions:11
- Comments:8 (2 by maintainers)
Top GitHub Comments
What is the reason for the Array constructor not returning an
unknown[]
? I’m a big fan of purgingany
from all of the TypeScript standard libraries, perhaps if it is too big of a change it can be added to the 4.0 todo list?@markrian The compiler and its options aren’t the problem here, it’s this line: https://github.com/microsoft/TypeScript/blob/05d59a1f1a408968aab7ae5dda9eef5881643cf7/lib/lib.es5.d.ts#L1375
form the array constructor definitions https://github.com/microsoft/TypeScript/blob/05d59a1f1a408968aab7ae5dda9eef5881643cf7/lib/lib.es5.d.ts#L1374-L1383
if you don’t specify a type, it implicitly uses the constructor which has
any
explicitly used.I fear that it is too late for this to change as it will introduce many breaking changes in existing codebases. Maybe in typescript v4? We’ll see…