TypeScript has really cool string interpolation powers. We want to take this following query:
const query = `/home?a=foo&b=wow`
And turn it into an object like this:
const obj: Union.Merge<QueryParams> = {
a: "foo",
b: "wow",
}
This features autocomplete and if we change one of the query parameters, TypeScript will let us know that it's incorrect and give us autocomplete.
To accomplish this we start with creating a Query type and then splitting the query up on the ? character in order to get the query parameters. Make sure to grab the second element of the array because the first element is just the path.
type Query = typeof query
type SecondQueryPart = String.Split<Query, "?">[1]
Once we have the query split up, we'll split it again on each & character to get each individual query parameter.
type QueryElements = String.Split<SecondQueryPart, "&">
We are using the ts-toolbelt library to help us with the string manipulation.
Now we want to build our QueryParams type now that we have them all split up. First of all, we want each QueryElement. So we'll create a mapped type with [QueryElement in QueryElements[numbedr]].
type QueryParams = {
[QueryElement in QueryElements[number]]: {}
}
Then we can create key value pairs of each parameter by mapping again over the split QueryElement and setting the key to the first element of the split and the value to the second element of the split.
type QueryParams = {
[QueryElement in QueryElements[number]]: {
[Key in String.Split<QueryElement, "=">[0]]: String.Split<
QueryElement,
"="
>[1]
}
}
And we then do this funny thing. that we've seen in previous tips. We iterate over each each member of the object, since we don't want the type to be the nested structure, just the key value pairs of the query params.
type QueryParams = {
[QueryElement in QueryElements[number]]: {
[Key in String.Split<QueryElement, "=">[0]]: String.Split<
QueryElement,
"="
>[1]
}
}[QueryElements[number]]
And finally we Union.Merge the QueryParams to merge them all into an object.
const obj: Union.Merge<QueryParams> = {
a: "wonderful",
b: "wow",
}
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.