Yamato DaiwaE(CMA)S(cript) extensions

RawObjectDataProcessor — 最少理論

RawObjectDataProcessorを利用する際は、 JavaScript・TypeScript、 正確にはECMAScript規格考慮する必要が有る。 これらの注意点は当然、公式・非公式のリソースでドキュメント化されているが、多数の初心者プログラマーはそれらを知らない事も多い。

オブジェクト系データ分類化

「RawObjectDataProcessor」という名前の直訳から分かる通り、此のユーティリティクラスは オブジェクト型データ、つまりtypeof N === "object"という条件を満たした上で、 かつnullではないデータを扱う為のものである。 ところで、ECMAScript規格の観点では、 typeof nullも"object"となっている。 子プロパティなら、数型や文字列や真偽を含めて他の型を持つ事が出来る。 但し、現時点ではJSON互換のデータのみが 完全にサポートされている。 該当している型の定義は以下の通り。

将来的に、DateやBigIntの様な他の型の 子プロパティのサポートが追加される可能性は有る。 然し現時点では、外部ソースからデータを読み込んでJavaScriptオブジェクトに変換する場合、それらは通常 JSON互換であり、DateやBigInt 型のプロパティが必要な場合は後処理で文字列から変換出来る為、此の機能の需要はそれほど高くない。

さて、RawObjectDataProcessorは以下の4つのオブジェクトの サブタイプを扱っている。

↓ キーの型 / ➝ 要素数固定任意
文字列固定構造オブジェクト連想配列
非負整数タプルインデックス配列

固定構成のオブジェクト

これらのオブジェクト・サブタイプでは、あり得る全ての プロパティ名が予め判明している事が前提となる。デモで使用されているSampleType型は、此の様なオブジェクト・サブタイプの例である。

固定構造である事は、多態的な(ポリモフィックな)プロパティを禁止するものではないが、 以下の例の様に、あり得る選択肢が予め分かっている必要がある。

此の型のオブジェクトは、最も一般的である。 クライアントとサーバー間等で送受信されるシリアライズされたデータは、殆どの場合此の形式。 JSONやYAML形式等のファイルに保存される設定も、通常はこの形式である (例えばTypeScriptの設定ファイルのtsconfig.json)。

連想配列型のオブジェクト

連想配列は、固定構造オブジェクトとは異なり、プロパティ名が事前に 分かっておらず、要素数も0から最大整数範囲内ならいくらでも有り得る。

ESMAScript 2015規格以前は、此の様な配列として 通常のオブジェクトが使用されていた。 出力JavaScriptコードの観点では、固定構造オブジェクトと何ら 変わりない。 TypeScriptでは、こうした連想配列は以下の何れかのの方法で アノテーションされる。

ESMAScript 2015規格で導入されたMap データ型を連想配列と呼ぶかどうかは、其の配列が何れでもの型の キーを許容するかどうかに依存する。 特にMapはオブジェクト型のキーを禁止していない。 何れにせよ、Map型はJSONと互換性がない。 然し、Mapを二次元のインデックス配列に変換する事で、互換性を持たせる事が出来る。 此の場合、各子配列の1番目の 要素をキー、2番目の要素を値とする。

頻繁に使用される連想配列の他の例として、package.jsonの多くのフィールド (scripts、dependencies、 devDependencies、 peerDependencies等)が挙げられる。

RawObjectDataProcessorは当然、文字列のキーを持つ 通常の連想配列をサポートしているが、JSONとの互換性が無い為、 Map型の入力データはサポートしていない。 但し、後処理機能を利用する事で、目的のデータをMapに変換する事は可能である。

指数配列

要素の順番が不可欠であり、各要素への アクセスがインデックスという0から始まる整数 に行わるコレクションの一種類である。 日本語でも英語でも、単に「配列」(array(s))と言う場合、連想配列では なくインデックス配列を指す事が多い。

多くの静的型付け言語(例えばC++、C#、Java)では、 通常のインデックス配列は要素数が 固定されており、多くの場合、要素の型も 統一されている。 要素の追加や削除が必要な場合は、専用のコレクションが使用される。 これ等は概念的には同じインデックス配列だが、内部で標準的な配列 を別のものに差し替える事に依り要素の追加・削除を可能にしている。

ECMAScriptに関しては、インデックス配列はArrayというクラス の様なオブジェクトのインスタンスである (X instanceof Arrayは真)。 こうしたインデックス配列は柔軟に操作出来る(具体的には、全く異なる型の要素を指定したり、 要素を追加・削除したり出来る)、今のところ追加のコレクションの必要性はない。

TypeScriptでインデックス配列をアノテーションするには、以下の何れかの方法がある。

固定構造オブジェクトと同様に、インデックス配列は最も一般的なデータ型の一つであり、 至る所で広く使われている。 固定構造オブジェクトや連想配列とは異なり、インデックス配列は要素の順序を 保証する為、順番の考慮が不可欠な場合、変わりの無いものになっている。

タプル

概念的には、タプルとは要素数が固定された# [+Term__Contrast--YDID 配列](一般的にはインデックス配列に限らない)のものである。

ECMAScript 2025規格(前述のECMAScript 2015と混同しない事) 以前は、JavaScriptに要素数を制限した配列 作成専用の機能は無かった。 TypeScriptでは、「タプル」(「tuple」)という用語は、 以下のようにアノテーションされるインデックス配列のみに適用されていた。

ECMAScript 2025規格では、新しいタプル型が登場した。 此れは要素数が固定されている事に加え、初期化後は読み取り専用と成る。 それで不変性を保証する為に、ArrayやMapや Set等を含めて、如何なるオブジェクトのサブタイプが 禁じてある。 此のデータ型は未だ非常に新しい為、様々な環境で広くサポートされる迄には時間がかかるだろう。 又、其の制限の為広く普及しない事も予想され、当然ながらRawObjectDataProcessorは此のデータ型を サポートしていない。 其の為、以降は既にRawObjectDataProcessorと互換性がある TypeScriptのタプルについて述べる。

タプルはそれほど一般的ではないが、使用例はある。 例えば、ReactのuseState関数は、2つの要素からなる タプルを返す。 全てではないが、多くのESLintルールの設定も、2番目の要素が 任意ではあるが、強いて言えば「タプル」と呼ぶ事が出来る。 何れにせよ、2つの位置それぞれに特定の型の要素が期待されており、 此れがタプルの主な特徴である。