toJson(options) {
		const childOptions = this._createChildOptions(options, {
			forToString: false
		});
		/** @type {KnownStatsCompilation} */
		const obj = {};
		obj.children = this.stats.map((stat, idx) => {
			const obj = stat.toJson(childOptions.children[idx]);
			const compilationName = stat.compilation.name;
			const name =
				compilationName &&
				identifierUtils.makePathsRelative(
					stat.compilation.compiler.context,
					compilationName,
					stat.compilation.compiler.root
				);
			obj.name = name;
			return obj;
		});
		if (childOptions.version) {
			obj.version = obj.children[0].version;
		}
		if (childOptions.hash) {
			obj.hash = obj.children.map(j => j.hash).join("");
		}
		/**
		 * @param {StatsCompilation} j stats error
		 * @param {StatsError} obj Stats error
		 * @returns {StatsError} result
		 */
		const mapError = (j, obj) => ({
			...obj,
			compilerPath: obj.compilerPath ? `${j.name}.${obj.compilerPath}` : j.name
		});
		if (childOptions.errors) {
			obj.errors = [];
			for (const j of obj.children) {
				const errors =
					/** @type {NonNullable<KnownStatsCompilation["errors"]>} */
					(j.errors);
				for (const i of errors) {
					obj.errors.push(mapError(j, i));
				}
			}
		}
		if (childOptions.warnings) {
			obj.warnings = [];
			for (const j of obj.children) {
				const warnings =
					/** @type {NonNullable<KnownStatsCompilation["warnings"]>} */
					(j.warnings);
				for (const i of warnings) {
					obj.warnings.push(mapError(j, i));
				}
			}
		}
		if (childOptions.errorsCount) {
			obj.errorsCount = 0;
			for (const j of obj.children) {
				obj.errorsCount += /** @type {number} */ (j.errorsCount);
			}
		}
		if (childOptions.warningsCount) {
			obj.warningsCount = 0;
			for (const j of obj.children) {
				obj.warningsCount += /** @type {number} */ (j.warningsCount);
			}
		}
		return obj;
	}
@param {(string | boolean | StatsOptions)=} options stats options
@returns {StatsCompilation} json output