Skip to main content

Parse Query String into Object

parseQueryString​

Parses a query string (optionally starting with ?) into a JavaScript object.
Supports arrays for duplicate keys, and can intelligently convert string values to primitives (numbers, booleans, null).

Import​

import { parseQueryString } from 'nhb-toolbox';
import { getQueryStringAsObject } from 'nhb-toolbox';
import { queryStringToObject } from 'nhb-toolbox';
// All 3 alias for the same utility

Function Signature​

parseQueryString<QParams extends ParsedQueryGeneric>(query: string, parsePrimitives = true): QParams

Usage Examples​

parseQueryString('a=1&b=hello');
// Returns: { a: 1, b: 'hello' }

API Reference​

Parameters​

NameTypeDescription
querystringThe query string to parse (with or without starting ?).
parsePrimitivesbooleanWhether to parse primitive-like strings ("false", "1", "null", etc). Defaults to true.

For better type intellisense for the returned object, pass a generic type that extends to ParsedQueryGeneric

Returns​

A JavaScript object (StrictObject) where each key is a string and each value may be:

  • string
  • number
  • boolean
  • null
  • string[], number[], boolean[], or null[]

Types​

type ParsedQueryGeneric = Record<string, NormalPrimitive | NormalPrimitive[]>;

Key Features​

  1. Flexible Input: Accepts query strings with or without a leading ?.
  2. Arrays from Multiple Keys: If a key appears more than once, you get an array.
  3. Automatic Primitive Parsing: Converts "1" β†’ 1", "true" β†’ true", "null" β†’ null" by default.
  4. Safe: Does not touch or depend on the browser’s window.location.

Aliases​

This function is also exported as:

  • getQueryStringAsObject
  • queryStringToObject

Limitations​

  1. No Deep Objects: Does not generate nested objects for dotted or bracketed keys (e.g., a.b=1 stays flat).
  2. Empty Key Handling: Keys without a value (e.g., foo&b=2) will be parsed with foo as an empty string "".
  3. No Key Decoding Customization: Uses standard URL decoding.

Notes​

  • Type Guessing: Primitive parsing is based on string matching; "012" becomes number 12, not "012" unless parsePrimitives = false.
  • Setting parsePrimitives: false is useful when you want all values as strings, like in typical form posts.
  • Arrays are always returned for duplicate keys, regardless of primitive type.
  • All values are string unless parsing is enabled (default).
  • Parsing URLs or query strings in client-side and server-side environments.
  • Reading user input or redirects where the string isn’t available on window.location.search.
  • Back-end parsing of GET query strings for API endpoints.

Conclusion:
parseQueryString turns any query string into a highly usable JavaScript object, supporting advanced parsing and multi-value keys. It works with any string input, making it ideal for shared or non-browser environments.


parseQueryStringLiteral​

Parses a literal query string (optionally starting with ?) into a strictly typed JavaScript object.
This function is designed for use with literal string types to provide maximum TypeScript type safety and inference. It actually returns shows the runtime value as type!

Import​

import { parseQueryStringLiteral } from 'nhb-toolbox';
import { literalQueryStringToObject } from 'nhb-toolbox';
// Both alias are for the same utility

Function Signature​

parseQueryStringLiteral<Q extends string>(query: Q): ParsedQuery<Q>

Usage Examples​

parseQueryStringLiteral('a=1&b=hello');
// Returns: { a: '1', b: 'hello' }
// Typed as: { a: '1'; b: 'hello' }

API Reference​

Parameters​

NameTypeDescription
queryQThe literal query string to parse (with or without ?).

Returns​

A strictly typed JavaScript object (ParsedQuery<Q>) where each key is inferred from the query string and values are properly typed as:

  • string for single values
  • string[] for multiple values with the same key

Key Features​

  1. Literal Type Inference: Provides maximum TypeScript type safety by inferring types from literal string inputs.
  2. Array Support: Automatically creates arrays for duplicate keys.
  3. Flexible Input: Accepts query strings with or without a leading ?.
  4. Strict Typing: Returns properly typed objects based on the input query string structure.

Aliases​

This function is also exported as:

  • literalQueryStringToObject

Comparison with parseQueryString​

FeatureparseQueryStringLiteralparseQueryString
Type InferenceInfers from literal stringsGeneric object type
Primitive ParsingNo (returns strings only)Yes (converts to numbers, booleans, null)
Use CaseLiteral string types with strict typingGeneric query strings with primitive conversion
PerformanceFaster (no type conversion)Slower (due to primitive parsing)
  • When working with literal string types and maximum TypeScript type safety is required
  • API endpoints with known, fixed query parameter structures
  • Configuration parsing where the query structure is statically known
  • When you need strict type inference without runtime type conversion

Notes​

  • String Values Only: Unlike parseQueryString, this function does not convert primitive values - all values remain as strings or string arrays.
  • Literal Types: For best TypeScript inference, use as const with your query strings.
  • No Browser Dependency: This function does not access or depend on window.location.search.
  • URL Decoding: Uses standard URL decoding for parameter values.

Example with Strict Typing​

// With literal type inference
const configQuery = 'theme=dark&lang=en&features=search';
const config = parseQueryStringLiteral(configQuery);
// config is returned and typed as: { theme: 'dark'; lang: 'en'; features: 'search' }

// With multiple values
const filterQuery = 'category=books&category=movies&sort=rating';
const filters = parseQueryStringLiteral(filterQuery);
// filters is returned and typed as: { category: ['books', 'movies']; sort: string }

Conclusion:
parseQueryStringLiteral provides maximum TypeScript type safety for parsing query strings from literal types, making it ideal for scenarios where the query structure is known at compile time and strict typing is required.