TypeScriptの `ReadonlyArray<T>` を使いやすくするためにtslintを活用する

最近、Kibelaのtslint configの Rule: array-type を "generics" にしました:

+     "array-type": [
+       true,
+       "generic"
+     ],

以前は特に指定しておらず、 T[]Array<T> が混在してていて、それでよしとしていました。今でも、混在することによるデメリットは特にないと思っていいます。ただ、 Array<T> には一つだけメリットがあったのでこちらに統一することにしました。 autofixできるので、エディタ上では T[] と書いて保存時にtslintに Array<T> に直させるということができるため、導入のデメリットがないというのも大きいです。

さて Array<T> のメリットは、 ReadonlyArray<T> に直しやすいということです。 ReadonlyArray<T>Array<T> から破壊的変更を伴うメソッド(mutation methods)を取り除いたインターフェイスで、特にReactではstateやpropsに破壊的変更を与えてはいけないということになっているので、積極的に使うメリットがあります。

ReadonlyArray<T> についてTypeScriptの公式マニュアルではほとんど触れられていませんが、インターフェイスの章にすこしだけ記述がありますね。

https://www.typescriptlang.org/docs/handbook/interfaces.html

TypeScript comes with a ReadonlyArray<T> type that is the same as Array<T> with all mutating methods removed, so you can make sure you don’t change your arrays after creation:

let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = a;
ro[0] = 12; // error!
ro.push(5); // error!
ro.length = 100; // error!
a = ro; // error!

なお同様に ReadonlyMap<K, V>ReadonlySet<T> もあるようです。