带有只读键的打字稿字典

时间:2017-01-31 09:11:01

标签: dictionary typescript readonly

是否可以使用只读密钥在typescript中声明字典类?

declaration of dictionary class with readonly keys

代码:

class Dictionary {
    readonly[key: string]: string;

    constructor(props: Dictionary) {
        for (const key in props) {
            this[key] = props[key];
        }
    }
}

通常在构造函数中设置readonly属性的值,但是编译器在这里抱怨"类型' Dictionary'的索引签名。只允许阅读'。

1 个答案:

答案 0 :(得分:1)

我不确定这是否符合设计,the docs对此感到困惑:

  

现在可以使用readonly声明属性或索引签名   修饰符被认为是只读的。

可是:

  

只读属性可能具有初始值设定项,可能已分配给   同一类声明中的构造函数,否则   不允许对只读属性进行分配

因此,虽然属性和索引签名都可以只读,但也许只能在构造函数中分配属性 不确定,你可以打开一个问题并找出答案。

然而,你可以使用Object.assign,它不会以编译错误结束,并且它也会清除代码:

class Dictionary {
    readonly[key: string]: string;

    constructor(props: Dictionary) {
        Object.assign(this, props);
    }
}

let d1 = new Dictionary({ key1: "one", key2: "two" });
console.log(d1); // Dictionary {key1: "one", key2: "two"}

let d2 = new Dictionary(d1);
console.log(d1); // Dictionary {key1: "one", key2: "two"}

code in playground

修改

使用Object.assign优于您的for / in循环,以下为例:

class A {
    [key: string]: any;

    constructor() {
        this["k1"] = "v1";
        this["k2"] = "v2";
    }

    method() {}
}

let a = new A();
let a1 = Object.assign({}, a);
console.log(a1); // { k1: "v1", k2: "v2" }

let a2 = {};
for (const key in a) {
    a2[key] = a[key];
}
console.log(a2); // { k1: "v1", k2: "v2", method: () }

code in playground

正如您所看到的,使用for / in循环也将迭代原型属性,这可能不是您想要的。
Object.assign没有遇到此问题。

另一种选择是使用Object.keys

let a3 = {};
Object.keys(a).forEach(key => a3[key] = a[key]);
console.log(a3); // { k1: "v1", k2: "v2" }