/**
* Parses and decodes a complete URL query string into a typed dictionary object.
*
* @param queryString - The URL query string (with or without leading '?').
* @returns An object mapping keys to their decoded values or arrays of values.
*/
function parseAndDecodeQuery(queryString: string): Record<string, string | string[]> {
// Remove leading '?' if present
const cleanQuery: string = queryString.startsWith('?') ? queryString.slice(1) : queryString;
// URLSearchParams automatically handles decoding and '+' to space conversion
const params: URLSearchParams = new URLSearchParams(cleanQuery);
const result: Record<string, string | string[]> = {};
for (const [key, value] of params.entries()) {
// Handle multi-value parameters by grouping them into an array
if (result[key]) {
const existing = result[key];
if (Array.isArray(existing)) {
existing.push(value);
} else {
result[key] = [existing, value];
}
} else {
result[key] = value;
}
}
return result;
}
// --- Program Execution ---
if (typeof module !== 'undefined' && require.main === module) {
const fullQuery: string = "search=typescript+tutorial&category=programming&tag=beginner&tag=frontend";
console.log("--- Full Query String Parsing ---");
console.log("Original Query:", fullQuery);
const decodedParams: Record<string, string | string[]> = parseAndDecodeQuery(fullQuery);
console.log("Decoded Object Result:");
for (const [key, value] of Object.entries(decodedParams)) {
console.log(` ${key} ->`, value);
}
}
/*
run:
--- Full Query String Parsing ---
Original Query: search=typescript+tutorial&category=programming&tag=beginner&tag=frontend
Decoded Object Result:
search -> typescript tutorial
category -> programming
tag -> [ 'beginner', 'frontend' ]
*/