如何在TypeScript中将类类型用作映射键?

时间:2017-01-25 13:57:31

标签: javascript typescript

我想在一个反映类的类型的键下的TypeScript(JavaScript)映射中存储一些信息。这是因为存储的数据实际上是静态的,并且适用于每种类型,而不是每个实例。

这是我如何宣布地图atm:

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

但是,number应该是类类型。如何实现这一目标?

1 个答案:

答案 0 :(得分:4)

如果您有一个对象({})作为地图,那么键必须是字符串(或自动转换为字符串的数字)。
在这种情况下,您可以使用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 property来自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");

code in playground