Typescript: Set MUST NOT allow to be number-indexed

Created on 3 Mar 2019  Â·  12Comments  Â·  Source: microsoft/TypeScript

I just experimented a _(what's the opposite of false positive ?)_ clean negative false negative _(thanks to @fatcerberus )_

TypeScript Version: 3.0.0-dev.201xxxxx
TypeScript Version: 3.3.3

NOTE : I had enabled downlevelIteration

Code

const leitters = new Set([ 'Aa', 'Bb', 'Cc' ]);
const leitter: string = leitters[0];

Expected behavior:

Second line MUST error

Actual behavior:

No error is reported...

Playground Link: https://bit.ly/2HcxmJa

Working as Intended

Most helpful comment

That's interesting, so if you do setObj.propDoesntExist you get an error even without --noImplicitAny but indexing is allowed in that situation. Seems a bit inconsistent, but I'm assuming this is for backward-compatibility reasons.

All 12 comments

--noImplicitAny?

That's interesting, so if you do setObj.propDoesntExist you get an error even without --noImplicitAny but indexing is allowed in that situation. Seems a bit inconsistent, but I'm assuming this is for backward-compatibility reasons.

Indexing anything (not just sets) by numbers/strings is allowed but generates an implicit any.

Hi @RyanCavanaugh ,

I thought the typing follow ES spec. So what is such a mapping provide that is useful ? Or the reverse question - What problem would arise if that index:number was not allowed ? I'm not sure to understand the working as intended label.

Thank you !

The issue is that we'd break thousands of existing projects that rely on this behavior.

You can cause the desired error by turning on the noImplicitAny compiler option.

Thank you @RyanCavanaugh .

Not to challenge you, but out of curiosity, would you help me find one such project ?
I'm curious to see what output can be expected from such a usage.

Kind Regards !

I’m going to go out on a limb here and assume that this behavior predates the introduction of index signatures. Thus, indexing is implicit any since otherwise you wouldn’t have been able to use the indexing syntax at all.

You surely pointed out it was an assumption @fatcerberus , but would you provide some reference to back you assumption ?

Thanks !

The basis of the assumption is that I’m pretty sure index signatures are a “newer” feature (read: later than 1.0) and if that’s the case then indexing would have had to be implicit-any prior to that to make it possible to index anything at all. But that means the behavior must now be maintained because there is surely older code that relies on it.

Index signatures have existed approximately forever.

An early complaint about TypeScript was "But I need to go outside the type system all the time", which was much truer then (and a much bigger concern) than it is now. So we allowed obj["s"].blah to always pass with the reasoning that you would 99% of the time prefer to write obj.s.blah, so writing obj["s"].blah was clear enough to indicate intent of doing something weird.

Another fact about JS is that indexed access with a number always coerces the indexing operand to a string, so it's "inconsistent" to say that e.g. obj[1] is illegal if obj["1"] is legal.

Index signatures have existed approximately forever.

Well... I stand corrected. :smile: Thanks!

OK @fatcerberus @RyanCavanaugh ,

Thank you for some history. It makes sense, at least.

Great day, both of you !

Was this page helpful?
0 / 5 - 0 ratings