Solución comentada
Publicado el 5 de septiembre de 2026La solución
type ParseQuery<S extends string> = S extends `${infer K}=${infer V}&${infer Rest}` ? Flatten<{ [P in K]: V } & ParseQuery<Rest>> : S extends `${infer K}=${infer V}` ? { [P in K]: V } : {}
El error más común
type ParseQuery<S extends string> = S extends `${infer K}=${infer V}&${infer Rest}` ? { [P in K]: V } & ParseQuery<Rest> : S extends `${infer K}=${infer V}` ? { [P in K]: V } : {}
El análisis es del todo correcto; el ensamblaje no. Cada paso recursivo aporta otro &, así que tres pares producen { a: "1" } & { b: "2" } & { c: "3" } — una cadena de tres objetos que se comporta como el que la comprobación pide, pero que no lo es. La recursión que construye objetos casi siempre necesita aplanarse al final.
Línea por línea
`${infer K}=${infer V}&${infer Rest}`La inferencia en literales de plantilla empareja desde la izquierda y toma la coincidencia más corta, así que
Kes"a",Ves"1"y todo lo que sigue al primer&pasa aRest. Un par por paso.{ [P in K]: V }Kllega como un tipo literal de cadena, que es un conjunto de claves perfectamente válido para un tipo mapeado de un solo miembro. Así un nombre analizado se convierte en una propiedad real.Flatten<... & ParseQuery<Rest>>Aplanar en cada paso, y no solo al final, evita que la intersección se haga profunda, y el resultado de cada paso ya tiene la forma que el siguiente espera.
Para recordar
Analizar una cadena a nivel de tipos son tres preguntas: ¿hay separador?, ¿es un último elemento suelto?, ¿o está vacía? Pon esas tres ramas en el orden correcto y la recursión se escribe sola.

