While trying to use the map type, I have repeatedly shot myself in the foot by trying to get and set elements using square brackets. I realize that I need to be using map.get(key)
and map.set(key,value)
but after using Python and C# dictionaries for so long, I'm having a hard time getting this through my thick skull.
let m = new Map<string, string>();
// This doesn't generate any error, though it
// doesn't do what someone might assume it
// would (doesn't add an element to the map)
m["foo"] = "bar"
// This doesn't generate an error either
m[1] = 2;
// This does generate an error, even though
// in javascript, m.foo means the same as
// m["foo"], so why does typescript treat
// them differently?
m.foo = "bar"
// This is what someone really should be
// doing to add an element to the map
m.set("baz", "qux")
The reason I use Typescript is usually because it prevents me from doing stupid things that the type does not support. However, in this case Typescript does not give an error. It doesn't seem to care that I'm trying to use square brackets to index into a map.
In fact, even for primitive data types like number it doesn't seem to mind me doing complete nonsense like this:
// Typescript allows you to index into any
// type, even a number?!??!?!
let x = 3;
let y = 4;
x["crazy"] = "yes";
// But again the behaviour is inconsistent
// between indexing with [] versus .
// The following is an error in Typescript.
x.crazy = "no"
Or even my own class.
class MyClass {
x: number;
}
let myInstance = new MyClass()
myInstance.x = 5;
myInstance["y"] = 10; // not an error
My questions are:
With default compiler settings you can indeed index into objects you shouldn't index into. This was probably done to ease migration from JS to TS.
You can enable the compiler checks regarding indexing (an other implicit uses of any) using the noImplicitAny
flag, or more generally you can enable extra checks using the strict
flag.