使用 ReadonlyMap<K, V> 类型

Posted

技术标签:

【中文标题】使用 ReadonlyMap<K, V> 类型【英文标题】:Using ReadonlyMap<K, V> type 【发布时间】:2018-10-07 08:45:30 【问题描述】:

TypeScript 定义了 ReadonlyMap&lt;K, V&gt; 接口,它是标准 javascript Map&lt;K, V&gt; 类型的不可变版本。

我们应该如何在代码中使用ReadonlyMap&lt;K, V&gt;

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

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

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

【问题讨论】:

【参考方案1】:

简短的回答:你做得对。

ReadonlyMap&lt;K, V&gt; 本质上是Map&lt;K, V&gt;超类型,因为它确实具有与Map&lt;K,V&gt; 匹配的方法和属性。因此,通过将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 版本,即使在运行时也是只读的,但只有当您有需要它的用例时,才值得付出努力。如果你不这样做,(而且你可能不这样做)那么不要担心它并继续按照你正在做的方式去做。

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

【讨论】:

以上是关于使用 ReadonlyMap<K, V> 类型的主要内容,如果未能解决你的问题,请参考以下文章

将 Map<K, List<V>> 转换为 Map<K, V> 其中 V 有 2 个对象列表

方法声明中的 Java 泛型 2 组 <K,V> 或 <T> [重复]

从 HashMap<K, V> 获取 List<K> ,其中 V 是 I 的实例 [关闭]

关于泛型集合Dictionary<K,V>的问题

排序

排序