Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does indexing in an array break type safety in TypeScript?

The whole point of adding static types to JavaScript is to provide some guarantees about type safety. I noticed that array indexing seems to break type safety without using any dirty tricks like as any or the not null assertion operator.

let a: Array<number> = [1,2,3,4];
let b: number = a[4]; //undefined

This code does not cause any TypeScript errors, even though it is plain to see that it will violate type safety. It seems to me that the type of an Array<T> acted upon by the index operator [] should be type T | undefined, however the TypeScript compiler treats it as if it was type T.

Upon further investigation, I discovered that this behavior applies to use of the index operator on objects as well. It would seem that the index operator is not type safe in any case.

class Example {
  property: string;
}

let c: Example = { property: "example string" }
let d: string = c["Not a property name"]; //undefined

Use of the index operator on an object with arbitrary key returns type any, which can be assigned to any type without causing type errors. However, this can be resolved by using the --noImplicitAny compiler option.

My question is why does something as basic as indexing on an array break type safety? Is this a design constraint, an oversight, or a deliberate part of TypeScript?

like image 426
Robert Stiffler Avatar asked Aug 08 '17 18:08

Robert Stiffler


People also ask

What does indexing an array do?

Indexing is an operation that pulls out a select set of values from an array. The index of a value in an array is that value's location within the array. There is a difference between the value and where the value is stored in an array.

Is TypeScript type safe?

Obviously it is not type safe. An incorrect parameter could be passed into the function and cause a run time error. Even if the parameters are being coded correctly, they will be hard to maintain. Let's say when an existing setting is renamed, the developer may not remember to update the parameters according.

What is type of index in TypeScript?

The indexing type is itself a type, so we can use unions, keyof , or other types entirely: type I1 = Person ["age" | "name"]; type I1 = string | number. type I2 = Person [keyof Person ]; type I2 = string | number | boolean.

How do you define a string array in TypeScript?

An array in TypeScript can contain elements of different data types using a generic array type syntax, as shown below. let values: (string | number)[] = ['Apple', 2, 'Orange', 3, 4, 'Banana']; // or let values: Array<string | number> = ['Apple', 2, 'Orange', 3, 4, 'Banana'];


1 Answers

To answer the why part of your question, it is because the developers of TypeScript thought that it would be too uncomfortable if you always had to check for undefined results when indexing an Array.

For example, the following code would not type-check:

var arr: number[]
var s = 0
for (var i in arr) {
  s += arr[i]
}

Furthermore, because JavaScript Arrays can be sparse, even if the index is known to not be out of bounds (as in, >= 0 and < arr.length), you can still get undefined, so there seems to be no way to fully infer actual unsafe indexing.

For more on this, see the issues TypeScript#13778 and TypeScript#11122.

like image 92
ᅙᄉᅙ Avatar answered Sep 22 '22 14:09

ᅙᄉᅙ