#Why is an empty array typed as `any[]`?
26 messages · Page 1 of 1 (latest)
My experience says that an empty array is inferred as never[], but suddenly today I am getting any[] everywhere I try, which is troubling.
I can even downgrade to TS 4.9.5 and still get any[] both in VSCode and using tsc
strict / noImplicitAny = true, without errors.
TS does some inference with unannotated array literals where the type adapts as you use it:
const x = [];
// ^? - const x: any[]
x.push(0);
console.log(x)
// ^? - const x: number[]
Huh, I was fairly certain it only happened with let.
If you don't ultimately do anything that infers the type, it'll error
function foo() {
const x = [];
// ^
// Variable 'x' implicitly has type 'any[]' in some locations where its type cannot be determined.
return x;
// ^
// Variable 'x' implicitly has an 'any[]' type.
}
I'm sure I've had errors where it wouldn't let me assign, because it was typed as never[]. Maybe that only occurs in certain situations.
It does similar things with let, I think. Doesn't even need to be arrays.
If you force some type of inference to happen then yeah, eg:
const x = [] satisfies unknown[]
// ^? - const x: never[]
let x;
// ^? - let x: any
if(Math.random() > 0.5) {
x = "foo"
} else {
x = 0;
}
console.log(x);
// ^? - let x: string | number
Yeah I'm aware of the let's ability to refine its type as you use it, but I wasn't aware it happens with const arrays.
Hmm, exporting it makes it into never[]
export const array = []
// ^? - const array: never[]
Generics are a big place it'll infer never[]
const ex = Promise.resolve([]);
// ^? - const ex: Promise<never[]>
export let array = []
// ^? - const array: never[]
Makes sense I support
Alright thanks @compact summit , learned something new.
And @crystal urchin
Yeah, this is pretty niche. Not sure I've ever used this behavior on purpose, but it's useful for making more JS code migratable to typescript with more type safety.
I could've sworn this behavior never existed with const arrays but maybe I just remembered wrong.