最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why does indexing in an array break type safety in TypeScript? - Stack Overflow

programmeradmin5浏览0评论

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 piler 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 piler 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?

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 piler 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 piler 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?

Share Improve this question asked Aug 8, 2017 at 18:27 Robert StifflerRobert Stiffler 7254 silver badges10 bronze badges 4
  • 2 That's an open issue. Please follow the discussion on github and let them know if you have any further ideas on this. – dotcs Commented Aug 8, 2017 at 18:35
  • It is an intentional work around because Javascript objects are not actually typed classes in the way Typescript likes to treat them. I have had to use this method several time when I receive back an object that I know may have had additional properties added by another function. – Ray Suelzer Commented Aug 8, 2017 at 20:37
  • I wrote a workaround: github./danielnixon/total-functions – danielnixon Commented Sep 30, 2019 at 1:51
  • 1 Thankfully Array.at behaves as you might expect, returning T | undefined – nireno Commented Apr 27, 2023 at 19:23
Add a ment  | 

3 Answers 3

Reset to default 6

Since Typescript version 4.1 we have the setting noUncheckedIndexedAccess. Enabling this basically works like what you describe - the inferred type of index access always includes undefined. In your example, the type of b bees T | undefined.

To answer the why part of your question, it is because the developers of TypeScript thought that it would be too unfortable 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.

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 piler option.

Yes. Use the noImplicitAny, if you care for strict safety. Also strict:true (which strictNullChecks as well as others).

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?

There are levels of safety. strict is the strongest. You choose how strict you want to be with your code.

More

From https://basarat.gitbooks.io/typescript/content/docs/options/intro.html

That said, traditionally programming languages have a hard boundary between what is and isn't allowed by the type system. TypeScript is different in that it gives you control on where you put the slider.

发布评论

评论列表(0)

  1. 暂无评论