javascript - Cum pot folosi un tip de clasă ca cheie într-o hartă în TypeScript?
Aș dori să stochez unele informații într-o hartă TypeScript (JavaScript) sub o cheie care reflectă tipul unei clase. Acest lucru se datorează faptului că datele stocate sunt de fapt statice și se aplică pe tip, nu pe instanță.
Iată cum am declarat harta momentan:
private static followSetsByATN: Map<number, FollowSetsPerState> = new Map();
Totuși, number ar trebui să fie în schimb un tip de clasă. Cum se poate realiza acest lucru?
Răspuns #1
Dacă ai un obiect ({}) ca hartă, atunci cheile trebuie să fie șiruri de caractere (sau numere care sunt convertite automat în șiruri de caractere).
În acest caz, poți folosi metoda toString():
class A { }
console.log(A.toString());
Va afișa:
function A() {
}
De asemenea, poți folosi și proprietatea name:
console.log(A.name); // "A"
De asemenea, poți suprascrie metoda toString() pentru a returna ceva propriu:
class A {
static toString() {
return "class A";
}
}
console.log(A.toString()); // "class A"
Și apoi:
let m = {} as { [name: string]: string };
m[A.toString()] = "something";
// or
m[A.name] = "something";
Dacă folosești un Map, atunci toate cele de mai sus funcționează în continuare, dar nu ești restricționat să ai chei de tip șir, prin urmare poți folosi chiar clasa însăși:
let m = new Map<{ new (): A }, string>();
m.set(A, A.toString());
console.log(m.get(A)); // "class A"
Editează
Dacă aveți o instanță a unei clase, puteți obține clasa folosind proprietatea constructor:
let a = new A();
...
m.set(a.constructor, SOME_VALUE);
Proprietatea constructor provine din object și arată astfel:
interface Object {
/** The initial value of Object.prototype.constructor is the standard built-in Object constructor. */
constructor: Function;
...
}
Așadar, întotdeauna primești un Function și va trebui să faci conversia:
m.set(a.constructor as typeof A, SOME_VALUE);
Deoarece probabil nu știți tipul clasei, va trebui să faceți altceva.
Puteți să faceți cast la any, dar asta nu este foarte frumos.
Iată o soluție funcțională care ar trebui să funcționeze bine pentru tine:
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");
(cod în teren de joacă)
