diff --git a/.gitignore b/.gitignore index 96537549..a6fcea55 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .vscode +.idea node_modules *.log .DS_Store diff --git a/package.json b/package.json index 23083be2..51dd8b03 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "lint:fix": "eslint --fix --ext .ts . && prettier -w src test", "prepack": "pnpm build", "release": "pnpm test && changelogen --release && npm publish && git push --follow-tags", - "test": "pnpm lint && vitest run" + "test": "pnpm lint && vitest --run typecheck && vitest run" }, "devDependencies": { "@types/node": "^20.4.5", diff --git a/src/query.ts b/src/query.ts index f4c8d2f5..51925ff8 100644 --- a/src/query.ts +++ b/src/query.ts @@ -10,12 +10,17 @@ export type QueryValue = | number | undefined | null + | boolean + | Array | Record; export type QueryObject = Record; + export type ParsedQuery = Record; -export function parseQuery(parametersString = ""): ParsedQuery { +export function parseQuery( + parametersString = "" +): T { const object: ParsedQuery = {}; if (parametersString[0] === "?") { parametersString = parametersString.slice(1); @@ -38,7 +43,7 @@ export function parseQuery(parametersString = ""): ParsedQuery { object[key] = [object[key] as string, value]; } } - return object; + return object as T; } export function encodeQueryItem( diff --git a/src/utils.ts b/src/utils.ts index 7365c009..6892118f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,6 @@ import { $URL } from "./url"; import { parseURL, stringifyParsedURL } from "./parse"; -import { ParsedQuery, QueryObject, parseQuery, stringifyQuery } from "./query"; +import { QueryObject, parseQuery, stringifyQuery, ParsedQuery } from "./query"; import { decode } from "./encoding"; export function isRelative(inputString: string) { @@ -132,8 +132,10 @@ export function withQuery(input: string, query: QueryObject): string { return stringifyParsedURL(parsed); } -export function getQuery(input: string): ParsedQuery { - return parseQuery(parseURL(input).search); +export function getQuery( + input: string +): T { + return parseQuery(parseURL(input).search); } export function isEmptyURL(url: string) { diff --git a/test/query.test.ts b/test/query.test.ts index 8e454ecb..e7d446d4 100644 --- a/test/query.test.ts +++ b/test/query.test.ts @@ -76,6 +76,10 @@ describe("getQuery", () => { }, "http://foo.com/?param=3¶m=": { param: ["3", ""] }, "http://foo.com/?param=¶m=3": { param: ["", "3"] }, + "http://foo.com/?param=": { param: "" }, + "http://foo.com/?param=%7B%22a%22:%5B%7B%22obj%22:%5B1,2,3%5D%7D%5D%7D": { + param: '{"a":[{"obj":[1,2,3]}]}', + }, }; for (const t in tests) { diff --git a/test/types.test-d.ts b/test/types.test-d.ts new file mode 100644 index 00000000..e28c503e --- /dev/null +++ b/test/types.test-d.ts @@ -0,0 +1,14 @@ +import { describe, expectTypeOf, test } from "vitest"; +import { getQuery, parseQuery } from "../src"; + +describe("query", () => { + test("getQuery generic type support", () => { + const result = getQuery<{ foo: string }>("http://foo.com/?foo=bar"); + expectTypeOf(result).toEqualTypeOf<{ foo: string }>(); + }); + + test("parseQuery generic type support", () => { + const result = parseQuery<{ foo: string }>("http://foo.com/?foo=bar"); + expectTypeOf(result).toEqualTypeOf<{ foo: string }>(); + }); +});