```typescript
/**
 * Merge overlapping intervals in ascending order.
 *
 * @param intervals - A list of [start, end] pairs to be merged.
 * @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.
 */
export function mergeIntervals(intervals: number[][]): number[][] {
  // Check for invalid intervals
  if (!intervals.every(([start, end]) => start <= end)) {
    throw new Error('Invalid interval: start must be less than or equal to end');
  }

  // Sort the intervals by their start value
  const sortedIntervals = intervals.sort((a, b) => a[0] - b[0]);

  const mergedIntervals: number[][] = [];
  for (const [start, end] of sortedIntervals) {
    // If the current interval does not overlap with the last merged interval,
    // or if it is the first interval, merge it
    if (!mergedIntervals.length || start > mergedIntervals[mergedIntervals.length - 1][1]) {
      mergedIntervals.push([start, end]);
    } else {
      // Otherwise, update the end of the last merged interval to be the maximum
      // of its current end and the end of the current interval
      mergedIntervals[mergedIntervals.length - 1][1] = Math.max(mergedIntervals[mergedIntervals.length - 1][1], end);
    }
  }

  return mergedIntervals;
}
```