Why Typescript allow me to do this? No length check for Array

Viewed 815

Why Typescript allow me to use any array element without forcing me to check if the index is valid?

Here is what I mean

function return_array(p:boolean):string[]{
    return (p) ? ['s'] : [];
}

const arr = return_array(false);
arr[30].toUpperCase();

This will obviously lead me to an error

Cannot read property 'toUpperCase' of undefined 

Is this by design or am I missing something?

Playground Link

Edit

The real function is something like:

function return_array(p:boolean):string[]{
    // querying the db, it can return an empty array. 
    return db_response;
} 
3 Answers

By default, TS doesn't check if the value exists under a particular index in dynamic arrays (string[]). To ensure the type safety, you can do one of (or both):

  1. Narrow the return type to [string] | [] (since this is what your function is actually returning).
  2. Set noUncheckedIndexedAccess in your TS config (this will force you to checks for undefined elements anytime you're accessing an index).

your function is explicitly returning string[] and typescript believes it. here's what you could do: playground

Based on the value of parameter p, your function return_array returns either an array containing a single element 's' (when p == true) or an empty array (when p == false).

You call return_array(false) and store the result in a variable called arr. That means, that arr will be an empty array.

Then you want to access the 31st element of that empty array (note that array indexes start at 0). That element is undefined, since the array has no elements at all.

You cannot call toUpperCase on undefined, since undefined and null have no members.

Note that TypeScript just compiles to JavaScript. And the above code is valid JavaScript. The following code would work fine as well:

const arr: string[] = [];
arr[30] = 's';

This will result in an array where arr[0] to arr[29] are undefined and arr[30] will be 's'.

TypeScript's behavior is correct. It should not override any behavior from JavaScript. It's simply valid to access an out-of-bounds element in a JavaScript array.

Related