Search code examples
typescripttsconfig

TS configuration for safe array access


In this code

const arr = ['hello', 'world'];
const x = arr[2];
const y = arr[0.5];

arr is a string[], and 10 and 0.5 are numbers, so TS implies that 10 and 0.5 can index arr, therefore inferring that x and y are strings too, while at runtime they'll be undefined.

Is there a configuration option I can write in my tsconfig.json that basically tells typescript "if you're not sure that arr: T[] has an element at i, do not infer that arr[i] is a T"?


Solution

  • TypeScript 4.1 introduced support for checked indexed accesses, which can be enabled via the --noUncheckedIndexedAccess compiler option. If you turn that on, you get this behavior:

    const arr = ['hello', 'world'];
    const x = arr[10] // number | undefined
    console.log(x.toUpperCase()) // compiler error
    //          ~ <-- object is possibly undefined
    
    console.log(x?.toUpperCase()) // okay
    

    which is what you're looking for. This option is not included in the --strict suite of type checking features, because it can make the compiler complain even for code which is generally considered safe:

    for (let i = 0; i < arr.length; i++) {
        console.log(arr[i].toUpperCase()) // error!
        // -------> ~~~~~~
        // arr[i] is possibly undefined
    }
    

    So you'll have to decide if your desired behavior is worth the possible false warnings from the type checker, and if so, turn on --noUncheckedIndexedAccess explicitly.

    Playground link to code