类型,javascript,typescript,collections,immutability"/>

首页 > 解决方案 > 使用 ReadonlyMap类型

问题描述

TypeScript 定义ReadonlyMap<K, V>了标准 JavaScriptMap<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>而不仅仅是类型转换?

标签: javascripttypescriptcollectionsimmutability

解决方案


简短的回答:你做对了。

ReadonlyMap<K, V>本质上是 的超类型Map<K, V>因为它确实具有与 . 匹配的方法和属性Map<K,V>。因此,通过将 aMap作为 a返回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()例如,调用者不知道返回值始终是 astring并且不能直接在其上调用任何特定于字符串的方法。)

这种运行时行为的编译时禁止类似于readonly修饰符的工作方式。当属性为readonly时,如果您尝试修改它,TypeScript 会报错,即使修改会在运行时成功。

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

希望有帮助;祝你好运!


推荐阅读