RawObjectDataProcessor — Theoretical Minimum
When working with RawObjectDataProcessor, it is necessary to take into account some nuances of JavaScript/TypeScript, or rather, the ECMAScript standard. Such nuances, of course, are documented in official and unofficial sources, but many beginner programmers often do not know them.
Object Like Data Classification
As seen from the name "RawObjectDataProcessor", this utility class is intended for working with object-like data, that is, data satisfying the condition typeof N === "object", while not being null (and typeof null is also "object" from the viewpoint of the ECMAScript standard). However, child properties can have other types, including numeric, string or boolean. Nevertheless, at the moment, only JSON-compatible data is fully supported. The corresponding type has the following definition:
export type ParsedJSON = ParsedJSON_Object | ParsedJSON_Array;
export type ParsedJSON_Object = { [key: string]: ParsedJSON_NestedProperty; };
export type ParsedJSON_Array = Array<ParsedJSON_NestedProperty>;
export type ParsedJSON_NestedProperty =
number |
string |
boolean |
null |
ParsedJSON_Object |
ParsedJSON_Array |
undefined;
Although terms such as "objects" and "arrays" are often applied to JSON, it is necessary to understand that JSON is a string, and not an object. This is why the alias names given above starting with "parsed" word, and not just JSON_Object or JSON_Array.
In the case of ECMAScript-based languages, to get a regular object from a JSON-string, JSON.parse() is most commonly used. But although the JSON format originated from JavaScript (which is clear from the abbreviation — "JavaScript Object Notation"), most other popular programming languages also work with this data format, but there the JSON-string is converted into data types supported by the corresponding programming languages.
Support for other types of child properties, such as Date or BigInt, may be added in the future. But at the moment, this functionality is not very much in demand, since usually when reading data from external sources and converting it into a JavaScript object, they are compatible with JSON, and if properties of type Date or BigInt are needed, they can be converted from strings during post-processing.
So, RawObjectDataProcessor works with the following four subtypes of objects:
| ↓ Keys type / ➝ Elements count | Fixed | Arbitrary |
|---|---|---|
| String | Fixed structure object | Associative array |
| Non-negative integer | Tuple | Indexed array |
Fixed Schemas Objects
For these object subtypes, it is implied that the names of all possible properties are known in advance. The SampleType type from the demo is an example of such an object subtype:
type SampleType = {
foo: number;
bar: string;
baz: boolean;
hoge?: number;
fuga: string | null;
quux: {
alpha: number;
bravo: "PLATINUM" | "GOLD" | "SILVER";
};
};
A fixed structure is not a prohibition on polymorphic properties, however, the possible options must be known in advance, as in the example below.
type SampleTypeWithPolymopthocProperties = {
foo:
{ hoge: string; } |
{ fuga: number: }
bar: number:
baz: string;
};
This type of objects is the most popular one, because most often it is such data in serialized form that is sent from the client to the server and vice versa. The same type of data is usually representing the settings stored in files such as JSON, YAML, and so on (for example, the TypeScript configuration — usually tsconfig.json).
Associative Array-like Objects
Associative arrays, unlike fixed structure objects, can have an arbitrary number of properties, the names of which are not known in advance.
Before the ESMAScript 2015 standard, regular objects were used as such arrays, from the viewpoint of the output JavaScript code differing in no way from fixed structure objects. In TypeScript, such associative arrays are annotated in one of the following ways:
type AssociativeArray<ValueType> = { [ key: string ]: ValueType };
// or
type AssociativeArray<ValueType> = Record<string, ValueType>;
The Map data type introduced in the ESMAScript 2015 standard may or may not be called an associative array depending on whether arbitrary type keys are allowed for such arrays. In particular, Map does not prohibit object-like keys. In any case, the Map data type is incompatible with JSON, however, such compatibility can be achieved by converting a Map into a two-dimensional indexed array, where in each child array, the first element is the key, and the second is the value:
const sampleMap: Map<string, number> = new Map([
[ "alpha", 1 ],
[ "bravo", 2 ],
[ "charlie", 3 ]
]);
const serializedMap: string = JSON.stringify(Array.from(sampleMap.entries()));
Other examples of frequently used associative arrays are many fields of package.json — scripts, dependencies, devDependencies, peerDependencies, and so on.
RawObjectDataProcessor, of course, works with regular associative arrays, which are objects with string keys, but it does not support input data of the Map type due to their incompatibility with JSON. Nevertheless, with the help of the post-processing functionality, you can convert the desired data to Map as well.
Indexed Arrays
A data collection where the elements sequence matters, and each element can be access by the indexes — integers starting from 0. It has happened English and many other languages that simply "array(s)" often refers specifically to indexed and not associative arrays.
In many strongly typed programming languages (for instance, C++, C#, and Java), regular indexed arrays have a fixed number of elements and often a single type of elements. If adding and/or removing elements is required, then specialized collections are used — from the conceptual viewpoint, the same indexed arrays, but providing the ability to add and/or remove elements by replacing one standard array with another internally.
As for ECMAScript, an indexed array is an instance of the class-like object Array (the statement X instanceof Array is truthy). Since such indexed arrays can be flexibly manipulated (in particular, you can specify elements of completely different types, add elements, and remove them), there is no need for additional collections yet.
An indexed array can be annotated in TypeScript in one of the following ways:
const indexedArray: string[] = [ "Alpha", "Bravo" ];
// Or
const indexedArray: Array<string> = [ "Alpha", "Bravo" ];
Like fixed structure objects, indexed arrays are one of the most popular data types, and therefore are widely used everywhere. Unlike fixed structure objects and associative arrays, indexed arrays guarantee the order of elements, which makes them irreplaceable where such order is critical.
Tuples
From a conceptual viewpoint, tuples are arrays (generally speaking, not only indexed ones) with a fixed number of elements.
Before the ECMAScript 2025 standard (not to be confused with the aforementioned ECMAScript 2015), there was no specialized tool in JavaScript for creating arrays of limited length. In TypeScript, the term "tuple" was applied only to indexed arrays annotated as follows:
const tupleOfTwoElements: [ string, number ] = [ "ALPHA", 1 ];
const tupleOfThreeElements: [ string, number, boolean ] = [ "BRAVO", 2, true ];
In the ECMAScript 2025 standard, the tuple — new data type — has been introduced, which, in addition to having a fixed number of elements, is also read-only after initialization, and therefore, to guarantee immutability, cannot contain objects of any subtypes, whether it's Array, Map, Set etc.. This data type is still very young, so it will take some time before it becomes widely supported in various runtimes. It can also be assumed that due to its limitations, it will not be widely used, and naturally, RawObjectDataProcessor does not support such a data type. In view of this, further we will be talking about TypeScript tuples, which are already supported with RawObjectDataProcessor.
Tuples of any type are not very popular, but there are some examples of their use. For instance, the useState function from React returns a tuple of two elements. The configuration of many (but not all) ESLint rules, in which the second element is optional, can be called "tuples" with a stretch. Nevertheless, an element of a specific type is expected at each of the two positions, which is the main feature of tuples.