繁体   English   中英

使用 ReadonlyMap<k, v> 类型</k,>

[英]Using ReadonlyMap<K, V> type

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>而不仅仅是类型转换?

简短的回答:你做对了。

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修饰符的工作方式类似。 当属性是readonly属性时,如果您尝试修改属性,TypeScript会抱怨,即使修改在运行时会成功。

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

希望有所帮助; 祝好运!

为了在运行时安全,我们可以这样表示ReadonlyMap

    const attrs: Map<string, string> = new Map();
    ...

    const trueRuntimeReadonlyMap: ReadonlyMap<string, string> = Object.freeze({
      entries: attrs.entries.bind(attrs),
      forEach: attrs.forEach.bind(attrs),
      get: attrs.get.bind(attrs),
      has: attrs.has.bind(attrs),
      keys: attrs.keys.bind(attrs),
      size: attrs.size,
      values: attrs.values.bind(attrs),
      [Symbol.iterator]: attrs[Symbol.iterator].bind(attrs)
    });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM