6

Why am I getting different type inference here for the array ?

const a = []; // any[]
const b = null ?? []; // never[] 

Demo here

Matthieu Riegler
  • 31,918
  • 20
  • 95
  • 134
  • Does this happen with `strictNullChecks`? – Andrey Tyukin Dec 21 '21 at 14:31
  • 2
    The strange part for me is that the first one is of type `any[]` and there is no compiler error, even though `noImplicitAny` is enabled. Normally I would expect an empty array to be typed as `never[]` if it cannot be inferred from context. The answer is likely that there is a special case for `const something = [];`. – kaya3 Dec 21 '21 at 14:35
  • 2
    https://github.com/microsoft/TypeScript/issues/36987, https://github.com/microsoft/TypeScript/issues/46492 – Andreas Dec 21 '21 at 14:39
  • 3
    More links: https://github.com/microsoft/TypeScript/issues/29795#issuecomment-461597638 https://github.com/microsoft/TypeScript/pull/11432 ; Discussion in the comments on a related question: https://stackoverflow.com/questions/54117100/why-does-typescript-infer-the-never-type-when-reducing-an-array-with-concat#comment95067334_54117175 ; Sorry, all this looks completely opinion-based. Inferring the "correct" `never[]` was confusing in most cases, so they've hard-coded something else for this very special case, and now that's just what it is. – Andrey Tyukin Dec 21 '21 at 14:40

1 Answers1

4

The "correct" thing to do would be to infer never[] for the empty array literal [], because the type of an array literal is the join of the types of its elements, and never is the join of an empty set.

However, since inferring never[] is usually not what the user intends when writing const a = [], this particular case received a very special treatment in the compiler, and now it starts by implicitly inferring any[], and then refining the type based on the subsequent control flow.

There does not seem to be any deeper meaning behind it: it's just what turns out to be the most useful in most cases.

Andrey Tyukin
  • 43,673
  • 4
  • 57
  • 93