使用ReadonlyMap <k,v =“”>类型

时间:2018-04-26 15:15:30

标签: javascript typescript collections immutability

TypeScript定义ReadonlyMap<K, V>接口,它是标准JavaScript Map<K, V>类型的不可变版本。

我们如何在代码中使用ReadonlyMap<K, V>

它不是从任何东西派生的,也不是声明构造函数。那么,我们应该这样做是否正确:

public publicApiMethod(): ReadonlyMap<K, V> {
    const map: Map<K, V> = new Map(...);
    return map as ReadonlyMap<K, V>;
}

或者有更好的方法来使用ReadonlyMap<K, V>而不仅仅是类型转换?

1 个答案:

答案 0 :(得分:8)

简短的回答:你做对了。

ReadonlyMap<K, V>本质上是Map<K, V>超类型,因为它的方法和属性与Map<K,V>的方法和属性相匹配。因此,通过将Map作为ReadonlyMap返回,您所做的只是扩大值的类型。顺便说一句,这意味着你可以跳过类型断言:

public publicApiMethod(): ReadonlyMap<K, V> {
    const map: Map<K, V> = new Map(...);
    return map; // no assertion necessary
}

就像你可以这样做:

public anotherMethod(): string | number {
    return "hey"; // always "hey", but assignable to string | number
}

好处是调用者不能自由地假设返回的值具有任何其他Map方法,并且尝试设置或清除映射内容将产生编译时错误,尽管事实是那些方法确实会在运行时存在。 (或者对于anotherMethod()示例,调用者无法知道返回值始终为string,并且无法直接调用任何特定于字符串的方法。)

此编译时禁止运行时行为与readonly modifier的工作方式类似。当属性为readonly时,如果您尝试修改属性,TypeScript会抱怨,即使修改在运行时也会成功。

如果您愿意,您可以实现自己的ReadonlyMap版本,即使在运行时也是只读的,但如果您有一个需要它的用例,那么这是值得的。如果你不这样做,(你可能没有),那么就不要担心它,并按照你的方式继续这样做。

希望有所帮助;祝你好运!