【问题标题】:How can I use a class type as a map key in TypeScript?如何在 TypeScript 中使用类类型作为映射键?
【发布时间】:2017-01-26 00:04:39
【问题描述】:

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

这是我声明 Map atm 的方式:

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

但是,number 应该是一个类类型。如何实现?

【问题讨论】:

    标签: javascript typescript


    【解决方案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 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)

    【讨论】:

    • 看起来已经很不错了。现在如何获取对象的类类型(例如:A 的实例)?你也可以加一下吗?
    • “对象的类类型”是什么意思?
    • let a: A = new A(); myMap.set(a.class, myValue); 那个 class 成员是悬而未决的问题。我通常不仅有类,还有许多类的各种实例。
    • 嗯,这给了我一个错误:“'Function' 类型的参数不可分配给'new () => A' 类型的参数。'Function' 类型不提供签名的匹配项' myMap.set(a.constructor, myValue); 调用上的新 (): A'"。
    • 很抱歉。再次检查我的答案,我添加了一个工作版本
    猜你喜欢
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 2011-11-12
    • 2018-06-25
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    相关资源
    最近更新 更多