```file:utils.ts
export function parseQueryString(qs: string): Record<string, string | string[]> {
  const result: Record<string, string | string[]> = {};

  if (qs.length === 0) {
    return result;
  }

  let query = qs;
  if (query.startsWith("?")) {
    query = query.slice(1);
  }

  if (query.length === 0) {
    return result;
  }

  const pairs = query.split("&");

  for (const pair of pairs) {
    if (pair.length === 0) {
      continue;
    }

    const eqIndex = pair.indexOf("=");
    let rawKey: string;
    let rawValue: string;

    if (eqIndex === -1) {
      rawKey = pair;
      rawValue = "";
    } else {
      rawKey = pair.slice(0, eqIndex);
      rawValue = pair.slice(eqIndex + 1);
    }

    const key = decodeComponent(rawKey);
    const value = decodeComponent(rawValue);

    const existing = result[key];

    if (existing === undefined) {
      result[key] = value;
    } else if (Array.isArray(existing)) {
      existing.push(value);
    } else {
      result[key] = [existing, value];
    }
  }

  return result;
}

function decodeComponent(component: string): string {
  try {
    return decodeURIComponent(component.replace(/\+/g, " "));
  } catch {
    return component;
  }
}
```