使用ReadonlyMap <K,V>类型

Ale*_*mov 8 javascript collections immutability typescript

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>;
}
Run Code Online (Sandbox Code Playgroud)

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

jca*_*alz 9

简短的回答:你做对了.

ReadonlyMap<K, V>本质上是一种超类型,Map<K, V>因为它确实具有与之相匹配的方法和属性Map<K,V>.因此,通过返回a Map作为a ReadonlyMap,您正在做的就是扩大值的类型.顺便说一句,这意味着你可以跳过类型断言:

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

就像你可以这样做:

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

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

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

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

希望有所帮助; 祝好运!