TypeScript: Tuple types accepting incorrect data

TypeScript Version: 2.6.0-rc

Code

let a: [string] = ['a', 'b'];

Expected behavior: Error: [string, string] is not compatible with [string].

Actual behavior: Compiles A-ok

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 16 (12 by maintainers)

Most upvoted comments

From #19536, we would like to consider one of two alternatives here:

  1. Treat all tuples as exact types, where the length property is manifest in the type, and two tuples are only assignable if they have the exact same length. Tuples will need to be ReadonlyArray for this to work. We will have to include this under a strict flag.
  2. Apply freshness rules on tuple literals, and flag excess members just like we do with objects.

Actually that example is disallowed. Excess assignment slots only work when the excess values are assignable to one of the member of the tuple. 🤷‍♂️

let a: [ string, number ] = [ 'hi', 12345, 'foo' ]; // ok
let b: [string] = ['hi', 12345]; // bad
let c: [string | number] = ['hi', 12345]; // ok

Personal opinion too, when the array is fresh, it should be strictly checked against the left hand, because as @deregtd indicates, how is that ever a desired situation? Especially considering how the following works:

let a: [string, number] = ['hi', 12345];
let b: [string] = a; // not assignable
let c: [string|number] = a; // ok

That, again, while maybe sound from a type system perspective, I can’t see why the assignment to b is bad while c is good from an identifying constructs that are likely to be errors. Either both are desirable, or neither.

I’ll implement (2) just to see how well it works, but I played with (1) and it works great. Note that #17765 implements (1) but that doesn’t include the open-length tuples from #6629 (or their improved spread checking).