Learn how to make a compile-time restriction that an array cannot be empty with dynamic type annotations.
Transcript
We've got an item types here, which is, as for now, simply an array of numbers in TypeScript. And we've got a bunch of variables which are going to test the correctness of the type we're going to create to improve here. And so there is an empty array, and we expect this one to fail when we create actually the non-empty array and we've got an array with one element, two elements and multiple elements, whatever and these are expected to pass since all of them has at least one element. So we can see that a TypeScript array obviously doesn't check how many elements does it include so all of them pass so we need to think of something better and let's create a tuple including one element and the two lines obviously pass since non-empty basically is expected to have one element but it has none and the one element array obviously pass, though the others also fail because one is expected and two are passed. So even if we replace a type annotation with a satisfies keyword, this is still not going to work as the same error is thrown because the same thing is being checked whether it uses a type annotation or satisfies.
So even if we like increase the number of elements we've got in the tuple, this is not going to work because we are just moving the length, moving the error around. So what we need to do is actually to create a dynamic number of elements, but not within the variable itself, but within the type, of course. And similar as we can have multiple or dynamic number of parameters passed to a JavaScript function we can have a dynamic number of types being included within a certain TypeScript type and this is called a variadic tuple. And that's basically the syntax. So here we can see that empty fails as expected, one element, two elements, multiple elements pass.
We can also make this agnostic to the number type. So we can make it a non-empty, which depends on a type parameter n, and let's replace that with n again, and let's make items basically a non-empty number array. And that's what we've got. Also, if we replace the annotation with the satisfies keyword, we'll also see that here in this case, does it satisfy the fact that this is a non-empty array, yes, but we've got the precise type over here. So thanks to the satisfies keyword, we don't lose the information about what it is.
So here we can see that yes, this does include two elements, though we make sure that it does satisfy the requirement. The difference with satisfies is that if we don't use it, well, we lose the information because of the type annotation.