When accessing array data in TypeScript, or even JavaScript for that matter, the most commonly used method is the bracket notation: []
. While that obviously works, there is a better solution, especially when caring about type safety: the .at()
method. It might be less known because it was introduced relatively recently in ECMAScript 2022, but it is actually safer and more intuitive. Let's dive into the details and check out what are its advantages.
Type difference
The key difference is how each method handles types:
- bracket notation
[]
: Always returns typestring
- array
.at()
: Always returns typestring | undefined
Lets look at an example:
const pkmn = ["Pikachu", "Charizard", "Mew"];
const pika = pkmn[0]
const pikaAt = pkmn.at(0)
Here you won't see any difference yet, as both methods will return "Pikachu". However things change when you use an out-of-bounds value or an empty array. Let's try to uppercase a value from an invalid index:
const pkmn = ["Pikachu", "Charizard", "Mew"];
const outsideArray = pkmn[4]
const outsideArrayAt = pkmn.at(4)
console.log("brackets test", outsideArray.toUpperCase()) // Throws TypeError
console.log("array at test", outsideArrayAt?.toUpperCase()) // Safely returns undefined
While the .at()
method safely returns undefined when an invalid index is accessed, the bracket method results in a TypeError: Cannot read properties of undefined (reading 'toUpperCase'). This can lead to runtime crashes or build failures, particularly in applications that rely on dynamic data.
The same principle applies to an empty array. For example:
const emptyArray: string[] = [];
const firstValue = emptyArray[0]; // TypeError
const firstValueAt = emptyArray.at(0); // undefined
Cleaner negative indexing
Accessing elements from the end of an array is something you'll often see when dealing with things like pagination or logging. This is where .at()
also comes in handy as it does negative indexing in a cleaner and more concise way:
const pkmn = ["Pikachu", "Charizard", "Mew"];
const lastTwo = [pkmn[pkmn.length - 1], pkmn[pkmn.length - 2]];
const lastTwoAt = [pkmn.at(-1), pkmn.at(-2)];
.at()
is simply better
While it might seem like a small addition to JavaScript, .at()
is simply a more intuitive way of accessing array elements. It improves type safety by returning undefined for invalid indices, reducing runtime errors and simplifies negative indexing. While the bracket notation []
still works, .at()
is a modern alternative that aligns with best practices in TypeScript and lets you avoid common errors. While it's not a must-use it's simply a better option for cleaner and type-safe code.