Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
22
rated 0 times [  26] [ 4]  / answers: 1 / hits: 16824  / 7 Years ago, wed, january 25, 2017, 12:00:00

I would like to store some information in a TypeScript (JavaScript) map under a key which reflects the type of a class. This is because the stored data is actually static and applies per type, not per instance.


Here's how I have declared the Map atm:


private static followSetsByATN: Map<number, FollowSetsPerState> = new Map();

However, number should be a class type instead. How can this be achieved?


More From » typescript

 Answers
44

If you have an object ({}) as a map then the keys must be strings (or numbers which are converted to strings automatically).

In this case you can use the toString() method:



class A { }
console.log(A.toString());


Will print:



function A() {
}


You can also use the name property:



console.log(A.name); // A


You can also override the toString() method to return something of your own:



class A {
static toString() {
return class A;
}
}
console.log(A.toString()); // class A


And then:



let m = {} as { [name: string]: string };
m[A.toString()] = something;

// or
m[A.name] = something;


If you are using a Map then all of the above still work, but you are not restricted to have string keys therefor you can use the class itself:



let m = new Map<{ new (): A }, string>();
m.set(A, A.toString());

console.log(m.get(A)); // class A





Edit



If you have an instance of a class, you can get the class using the constructor property:



let a = new A();
...
m.set(a.constructor, SOME_VALUE);


The constructor property comes from object and it looks like so:



interface Object {
/** The initial value of Object.prototype.constructor is the standard built-in Object constructor. */
constructor: Function;

...
}


So you always get a Function and you'll need to cast:



m.set(a.constructor as typeof A, SOME_VALUE);


As you probably don't know the type of the class, you'll need to do something else.

You can cast to any, but that's not very pretty.



Here's a working solution that should work well for you:



interface Base { }
type BaseContructor = { new (): Base };

class A implements Base { }
class B implements Base { }

let m = new Map<BaseContructor, string>();
let a = new A();
let b = new B();

m.set(a.constructor as BaseContructor, value);
m.set(b.constructor as BaseContructor, value);


(code in playground)


[#59207] Tuesday, January 24, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
pranavrorys

Total Points: 466
Total Questions: 87
Total Answers: 115

Location: Barbados
Member since Sun, Nov 27, 2022
2 Years ago
pranavrorys questions
Fri, May 27, 22, 00:00, 2 Years ago
Thu, Oct 28, 21, 00:00, 3 Years ago
Sat, May 30, 20, 00:00, 4 Years ago
Fri, Dec 20, 19, 00:00, 5 Years ago
;