Friday 12 June 2020

Typescript - Index signature

Did you know?


  1.  JavaScript can have object indices. if an object is passed as an index, toString() method will be called implicitly.  However, TypeScript supports only number and string indices. If you are using an object index, an explicit call to toString() should be made.
JavaScript Demonstration:

An object with an overriden toString() method which returns a string: 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
obj = {
  toString(){
    console.log('toString() called')
    return 'Hello'
  }
}


foo= {} // calls Object constructor
foo[obj] = 'world' // prints: 'toString() called'
console.log(foo[obj]) // prints: 'toString() called', followed by "world"
Console.log(foo['Hello']) // Note what is being passed as index. prints "world"
    
 
Now what will happen if the toString() method  has no return statement? Will it throw an error?

 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
obj = {
  toString(){
    console.log('toString() called')
  }
}


foo= {} // calls Object constructor
foo[obj] = 'world' // prints: 'toString() called'
console.log(foo[obj]) // prints: 'toString() called', followed by "world"
Console.log(foo['undefined']) // Note what is being passed as index. prints "world"


You can still use the string "undefined" as index to retrieve the value 'world' which you set to the index obj!

Suppose you have two object indices where you want to save two different values. These Objects have overriden toString() methods with no return value. Though the code might look like we are storing the values in two different objects, we are in fact storing them at the same key "undefined".

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
obj1 = { 
         toString() {
           console.log("xyz")}
      }

obj2 = {
         toString() {
           console.log("xyz")}
      }

foo={}
foo[obj1]="hello" // prints: xyz
foo[obj2]="world" // prints: xyz
console.log(foo["undefined"]) // prints: world

What will happen if the toString() is not overriden?


1
2
3
4
5
6
obj = {} // has default toString() of Object


foo= {} // calls Object constructor
foo[obj] = 'world' // prints: nothing
Console.log(foo['[object Object]']) // Note what is being passed as index. prints "world"



As per MSDN WEB DOCS :
If this method is not overridden in a custom object, toString() returns "[object type]", where type is the object type.
In the above code snippet , you will observe that the index used to retrieve the value is "[object Object]" 


TypeScript Demonstration:

1
2
3
4
5
6
7
let obj = {msg: "Hello"}

let foo: any = {};
foo[obj] = 'World'; // Error: Type '{ msg: string; }' cannot be used as an index type.

foo[obj.toString()] = 'World'; // explicitly call toStrict method of Object
console.log(foo["[object Object]"]); // toString called, World


As you can see , TypeScript will not permit you to use an object index. 


"Why do you even want to store a value at a location 
'[object Object]' ?? 😝"










References:




No comments:

Post a Comment

JS Animation for Beginners

Simple Spinner Animation The Start and Stop Spinner app example given in MDN docs (  Go to example  ) has one drawback. When you s...