5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

TypeScript: Array.isArrayを読み取り専用配列(readonly)に対応させる方法

Posted at

この投稿では、TypeScriptのビルトイン型定義のArray.isArrayを読み取り専用配列(readonly array)に対応する方法を紹介します。

Array.isArrayの問題点

TypeScriptのArray.isArrayメソッドの型宣言は次のようになっています。

interface ArrayConstructor {
    /* 中略 */
    isArray(arg: any): arg is any[];
    /* 中略 */
}
// from: https://github.com/microsoft/TypeScript/blob/9a75d2acc8f7175d1ada327a0e457f7ea1ea1c46/src/lib/es5.d.ts#L1440

このメソッドは型ガード関数で、戻り値はtype predicateになっています。これにより、if文などでArray.isAarrayを使った場合、変数が配列型に絞り込みがなされます。

Array.isArrayによりnumber[] | undefinedが絞り込まれる例

ところが、読み取り専用配列に対して、Array.isArrayを使って型の絞り込みを行うと、any[]型になってしまいます。

Array.isArrayによりreadonly number[] | undefinedがany[]になる例

読み取り専用配列に対応してほしいという声はあるようで、issueに上がっていますが解決されていません。

Array.isArrayを読み取り専用配列に対応する方法

この問題を解決するには、isArrayの型定義を上書きします。型の上書きには、宣言マージ(declaration merging)を応用します。具体的には、次のArrayConstructorインターフェースを定義します。

declare global {
  interface ArrayConstructor {
    isArray(arg: readonly any[] | any): arg is readonly any[];
  }
}

これを書いておくと、読み取り専用配列に対しても型の絞り込みがうまくいくようになります。

ちなみに、読み取り専用タプル(readonly tuple)に対してもちゃんと効くようになります。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?