![](/img/trans.png)
[英]How to properly handle type for es6 Map<K,V> functions when using Typescript?
[英]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.