前言
有天面试的时候,面试官问如何写 获取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
仍然包含其他值key
value
值, 那么这里我们递归解决就行了 - 判断逻辑是 如果么有包含
&
那么我们就构建对象,{ [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)