前言
有天面试的时候,面试官问如何写 获取url 参数类型应该怎么写?
- 当时回答用的是
infer,跟泛型还有递归,但是面试官说哪里需要用到泛型, 说参数不就是一个string吗,后来就不了了之了。 - 但回家想了一下,确实应该使用
泛型,我的解决思路是没有问题的
解决思路
- 比如当前
url为https://www.baidu.com?key12=0123123&key1=1, 那么我们要获取key12跟value: 0123123 - 先截取字符串
?之后的值,得到的结果是key12=0123123&key1=1 - 然后截取
${key}=${value}这个字符串, 得到的结果是key = key12,value = 0123123&key1=1, 你可以发现value仍然包含其他值keyvalue值, 那么这里我们递归解决就行了 - 判断逻辑是 如果么有包含
&那么我们就构建对象,{ [k in key]: value } - 最后递归合并对象即可
完整代码
type Merge<F, S> = {[key in keyof F | keyof S]: key extends keyof S ? S[key] : key extends keyof F ? F[key] : never};
type getKeys<T extends string> = T extends `${infer K}?${infer Rest}` ? Rest : ''
type keyToValue<T extends string> = T extends `${infer key}=${infer value}`
? value extends `${infer V}&${infer rest}`
? Merge<{[k in key]: V}, keyToValue<rest>>
: { [k in key]: value }
: {}
type A = getKeys<'https://www.baidu.com?key12=0123123&key1=1'>
type B = keyToValue<A>
const url = 'https://www.baidu.com?key12=0123123&key1=1'
function getParameter<T extends string>(url: T): keyToValue<getKeys<T>> {
const [ , format] = url.split("?");
const data = format.split("&")
const result = {} as keyToValue<getKeys<T>>
data.forEach((_item) => {
const [key, value] = _item.split("=")
result[key] = value
})
return result
}
const q = getParameter(url)