```ts
export function regionTotals(grid: number[][], queries: number[][]): number[] {
    if (grid.length === 0 || grid[0].length === 0) {
        throw new Error("Grid must be non-empty.");
    }

    const rows = grid.length;
    const cols = grid[0].length;

    // Validate grid
    for (let i = 1; i < rows; i++) {
        if (grid[i].length !== cols) {
            throw new Error("All rows must have the same length.");
        }
    }

    // Validate queries
    for (const query of queries) {
        if (query.length !== 4 ||
            typeof query[0] !== 'number' || typeof query[1] !== 'number' ||
            typeof query[2] !== 'number' || typeof query[3] !== 'number') {
            throw new Error("Query must be a list of exactly four integers.");
        }

        const [top, left, bottom, right] = query;
        if (top >= bottom || left >= right || top < 0 || left < 0 || bottom > rows || right > cols) {
            throw new Error("Invalid query bounds.");
        }
    }

    // Compute prefix sum table
    const prefixSum: number[][] = Array.from({ length: rows + 1 }, () => Array(cols + 1).fill(0));
    for (let i = 1; i <= rows; i++) {
        for (let j = 1; j <= cols; j++) {
            prefixSum[i][j] = prefixSum[i - 1][j] + prefixSum[i][j - 1] - prefixSum[i - 1][j - 1] + grid[i - 1][j - 1];
        }
    }

    // Compute region totals
    return queries.map(([top, left, bottom, right]) => {
        const [i, j, k, l] = [top + 1, left + 1, bottom + 1, right + 1];
        return prefixSum[k][l] - prefixSum[i - 1][l] - prefixSum[k][j - 1] + prefixSum[i - 1][j - 1];
    });
}
```