0

From typescriptlang.org:

TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.

This is false.

Here, I have the error:

An index expression argument must be of type 'string', 'number', 'symbol', or 'any'

This is caused by the [ inline-map ] expression:

test = { true: 'Y', false: 'N', undefined: 'IDK', null: 'Nah', 0: 'none' }[ true ];

Isn't a Boolean a type "<any>"??? Pretty infuriating, since I use this syntax left right & center.

Moreover, the following works just fine:

{ true: 'Y', false: 'N', undefined: 'IDK', null: 'Nah', 0: 'none' }[ undefined ];
{ true: 'Y', false: 'N', undefined: 'IDK', null: 'Nah', 0: 'none' }[ null ];

The colloquial, "Anything that's legal JavaScript is perfectly legal TypeScript" is outright a false statement.

Obviously, I can write it as:

{ true: 'Y', false: 'N', undefined: 'IDK', null: 'Nah', 0: 'none' }[ ''+true ];

But why is Boolean not of type any???

Is this a bug of TypeScript?

Has this been reconciled in TS 2.1?

Can I correct this issue in tsconfig.json or another way?

Jordan Running
  • 102,619
  • 17
  • 182
  • 182
Cody
  • 9,785
  • 4
  • 61
  • 46
  • 2
    `Boolean` and `any` are different types. `Boolean` is compatible with `any`, but it does not say `compatible with type string, ... or any`, it says `must be of type ...`. Also, errors reported by typescript do not prevent it from compiling your source code to javascript (unless you set `--noEmitOnError` compiler option explicitly), so yes, it **is** a superset of JavaScript. – artem Jan 19 '17 at 19:20
  • Related: http://stackoverflow.com/questions/26269564/error-ts2342-an-index-expression-argument-must-be-of-type-string-number-o – Jordan Running Jan 19 '17 at 19:22
  • 1
    does `obj[bool] ` work? in general, claims made by frameworks are often exaggerated... – dandavis Jan 19 '17 at 19:23
  • 1
    @dandavis It [does appear to work](http://www.typescriptlang.org/play/#src=let%20x%20%3D%20%7B%7D%3B%0D%0Ax%5Btrue%5D%20%3D%201%3B%0D%0Ax%5B%3Cany%3E%20true%5D%20%3D%201%3B). – Jordan Running Jan 19 '17 at 19:35
  • 1
    This may help you: http://stackoverflow.com/questions/41750390/what-does-all-legal-javascript-is-legal-typescript-mean/41750391#41750391 – Ryan Cavanaugh Jan 19 '17 at 19:47
  • Nice. Thx everyone. I was under the assumption that `any` was basically a Liskov type for ... well, any type; so any type would be valid as a Liskov Substitute. Thx again. – Cody Jan 19 '17 at 20:16
  • 1
    From my experience, `is a` relationship is not very meaningful for structural types (all types in typescript except enums are structural). `is a` is one-way only and transitive (A is a B and B is a C means A is a C). Structural typing is completely different beast, it's modeled with `A is assignable to B` relation, and `any` was deliberately made 2-way compatible with any type, so you have weird thing where `int` is assignable to `any` and `any` is assignable to `string` but not `int` assignable to `string` – artem Jan 19 '17 at 21:17
  • @artem, to clarify -- did you mean *`any` is assignable to `string`* or *`string` is assignable to `any`*? I imagined this to be an acyclical graph with `any` not having links outward; at least in terms of `is a` relationships. Hope that makes sense. – Cody Jan 19 '17 at 22:14
  • Yes really `any` is assignable to `string`, [as said in the last paragraph here](https://www.typescriptlang.org/docs/handbook/type-compatibility.html): "These differ only in that assignment extends subtype compatibility with rules to allow assignment to and from any". So there are cycles. Also, according to typescript rules, `A assignable to B` and `B assignable to A` could both be true for different A and B. Example: `interface A { a: number; b?: string}; interface B { a: number }`. – artem Jan 19 '17 at 22:28
  • Basically the point of `any` is that it says "Yes that is OK" to literally any question asked of it by the type system. Can you be assigned from X? Yes. Can you be assigned to Y? Yes. Do you have property Z? Yes. – Ryan Cavanaugh Jan 19 '17 at 22:52

0 Answers0