javascript - 我如何在 TypeScript 中將類型作為映射鍵使用?
我想在 TypeScript(JavaScript)的映射中存儲一些信息,並以反映類型的鍵來存儲。這是因為存儲的數據實際上是靜態的,並且是對每種類型而不是每個實例適用。
這是我目前宣告這個地圖的方式:
private static followSetsByATN: Map<number, FollowSetsPerState> = new Map();
然而,number 應該是一個類型。如何才能實現這一點?
答案#1
如果你有一個物件({})作為映射,那麼鍵必須是字串(或是會自動轉換為字串的數字)。
在這種情況下,你可以使用 toString() 方法:
class A { }
console.log(A.toString());
將會列印:
function A() {
}
你也可以使用 name 屬性:
console.log(A.name); // "A"
你也可以覆寫 toString() 方法來返回你自己的內容:
class A {
static toString() {
return "class A";
}
}
console.log(A.toString()); // "class A"
然後:
let m = {} as { [name: string]: string };
m[A.toString()] = "something";
// or
m[A.name] = "something";
如果你使用的是 Map,上述所有方法仍然有效,但你不受限於必須使用字串鍵,因此你可以使用類本身:
let m = new Map<{ new (): A }, string>();
m.set(A, A.toString());
console.log(m.get(A)); // "class A"
編輯
如果你有一個類的實例,你可以使用 constructor 屬性來獲取該類:
let a = new A();
...
m.set(a.constructor, SOME_VALUE);
constructor 屬性來自 object,它看起來是這樣的:
interface Object {
/** The initial value of Object.prototype.constructor is the standard built-in Object constructor. */
constructor: Function;
...
}
所以你總是會得到一個 Function,並且你需要進行類型轉換:
m.set(a.constructor as typeof A, SOME_VALUE);
由於你可能不知道這個類別的類型,你需要做其他的事情。
你可以轉型為 any,但那樣看起來不是很好看。
這裡有一個可行的解決方案,應該對你很有用:
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");
(在遊樂場中的程式碼)
