Open rimo030 opened 4 months ago
type AddValue<O extends object, K extends keyof O, V> = { [key in keyof O] : key extends K ? O[key] extends any[] ? V extends O[key][number] ? O[key] : [...O[key], V] : O[key] extends V ? O[key] : [O[key], V] : O[key] } type ParseValue<T extends string, L extends object> = T extends `${infer K}=${infer V}` ? K extends keyof L ? AddValue<L, K, V> : L & Record<K, V> : T extends keyof L ? AddValue<L, T, true> : L & Record<T, true> type _ParseQueryString<S extends string, L extends object = {}> = S extends `${infer F}&${infer R}` ? _ParseQueryString<R, ParseValue<F, L>> : ParseValue<S, L> type ParseQueryString<S extends string> = S extends '' ? {} : Omit<_ParseQueryString<S>, never>
import type { Equal, Expect } from '@type-challenges/utils' type cases = [ Expect<Equal<ParseQueryString<''>, {}>>, Expect<Equal<ParseQueryString<'k1'>, { k1: true }>>, Expect<Equal<ParseQueryString<'k1&k1'>, { k1: true }>>, Expect<Equal<ParseQueryString<'k1&k2'>, { k1: true, k2: true }>>, Expect<Equal<ParseQueryString<'k1=v1'>, { k1: 'v1' }>>, Expect<Equal<ParseQueryString<'k1=v1&k1=v2'>, { k1: ['v1', 'v2'] }>>, Expect<Equal<ParseQueryString<'k1=v1&k2=v2'>, { k1: 'v1', k2: 'v2' }>>, Expect<Equal<ParseQueryString<'k1=v1&k2=v2&k1=v2'>, { k1: ['v1', 'v2'], k2: 'v2' }>>, Expect<Equal<ParseQueryString<'k1=v1&k2'>, { k1: 'v1', k2: true }>>, Expect<Equal<ParseQueryString<'k1=v1&k1=v1'>, { k1: 'v1' }>>, Expect<Equal<ParseQueryString<'k1=v1&k1=v2&k1=v1'>, { k1: ['v1', 'v2'] }>>, Expect<Equal<ParseQueryString<'k1=v1&k2=v1&k1=v2&k1=v1'>, { k1: ['v1', 'v2'], k2: 'v1' }>>, Expect<Equal<ParseQueryString<'k1=v1&k2=v2&k1=v2&k1=v3'>, { k1: ['v1', 'v2', 'v3'], k2: 'v2' }>>, Expect<Equal<ParseQueryString<'k1=v1&k1'>, { k1: ['v1', true] }>>, Expect<Equal<ParseQueryString<'k1&k1=v1'>, { k1: [true, 'v1'] }>>, ]