Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ReadonlyMap<K, V> type

TypeScript defines ReadonlyMap<K, V> interface which is immutable version of standard JavaScript Map<K, V> type.

How are we supposed to use ReadonlyMap<K, V> in our code?

It's not derived from anything and doesn't declare constructor. So, is it true that we just should do:

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

Or there are a better approaches to using ReadonlyMap<K, V> rather than just typecasting?

like image 555
Alexander Abakumov Avatar asked Apr 26 '18 15:04

Alexander Abakumov


1 Answers

Short answer: you're doing it right.

ReadonlyMap<K, V> is essentially a supertype of Map<K, V> since the methods and properties it does have match up with those of Map<K,V>. So by returning a Map as a ReadonlyMap, all you're doing is widening the type of the value. By the way, that means you can skip the type assertion:

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

Just like you could do this:

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

The benefit is that a caller is not free to assume that the returned value has any of the other Map methods, and trying to set or clear the map contents will produce a compile time error, despite the fact that those methods would indeed exist at runtime. (Or for the anotherMethod() example, the caller cannot know that the return value is always a string and can't directly call any string-specific methods on it.)

This compile-time prohibition of runtime behavior is similar to the way the readonly modifier works. When a property is readonly, TypeScript will complain if you try to modify it, even though the modification would succeed at runtime.

You could, if you wanted, implement your own version of ReadonlyMap that is read-only even at runtime, but that's only worth the effort if you have a use case that requires it. If you don't, (and you probably don't) then don't worry about it and keep doing it the way you're doing it.

Hope that helps; good luck!

like image 117
jcalz Avatar answered Oct 19 '22 16:10

jcalz