```typescript
/**
 * Returns the smallest list of non-overlapping pairs covering the same points,
 * sorted ascending by start. Intervals that merely touch (end === next start)
 * do merge. The function must be pure - it must not mutate the argument array
 * nor any of the inner arrays it was given, and every returned pair must be a
 * fresh array. Throws an Error for a pair whose start is greater than its end.
 */
export function mergeIntervals(intervals: number[][]): number[][] {
    if (!Array.isArray(intervals) || intervals.length === 0) {
        throw new Error('Input must be a non-empty array of [start, end] pairs');
    }

    const merged = [];
    for (const interval of intervals.sort((a, b) => a[0] - b[0])) {
        if (!merged.length || merged[merged.length - 1][1] < interval[0]) {
            merged.push(interval);
        } else {
            merged[merged.length - 1][1] = Math.max(merged[merged.length - 1][1], interval[1]);
        }
    }

    const result: number[][] = [];
    for (const interval of merged) {
        if (interval[0] <= interval[1]) {
            result.push(interval);
        } else {
            throw new Error(`Invalid interval: [${interval.join(', ')}]`);
        }
    }

    return result;
}
```