TypeScript 杂记八 《Query String Parser》
Posted 左手121
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TypeScript 杂记八 《Query String Parser》相关的知识,希望对你有一定的参考价值。
TypeScript 杂记八 《Query String Parser》
思路
- 求出每一个
k=v
,可能会出现下边的情况:aaa=1&bbb
aaa
type ParserHelper<
T extends string,
R extends Record<string, unknown[]> =
> = T extends `$infer A&$infer B`
? A extends `$infer K=$infer V`
? ParserHelper<B, Merged<R, K, V>>
: // aaa=1&bbb 情况,直接设置 bbb=true
ParserHelper<B, Merged<R, A, true>>
: T extends `$infer K=$infer V`
? Merged<R, K, V>
: T extends ""
? R
: // aaa 情况,设置 aaa=true
Merged<R, T, true>;
- 合并值
- 考虑到存在多个值的情况,需要采用元组形式。我们这里统一都采用元组形式
- 先不考虑数据重复的情况
- 如果 V 是一个空字符串则将 V 设置成 true
- 将 R[K] 和 V 进行合并
- 将 R 中对应的 K 移除
- 将新的 R 和新的 K V 合并
type Merged<
R extends Record<string, unknown[]>,
K extends keyof R,
V
> = V extends ""
? Merged<R, K, true>
: Omit<R, K> & Record<K, R[K] extends unknown[] ? [...R[K], V] : [V]>;
- 元组中的值去重
- 使用 K 来定义元组中所有的值(不重复,其结果为
"1" | "2" | true
形式) - R 用来存储最终的结果
- 如果 A 在 K 中,则表示重复,继续下一步
- 如果 A 不在 K 中,则表示唯一,新的 K 变成了
K | A
,R 变成了[...R, A]
- 当 T 为空的时候,返回结果 R。如果 R 里边只有一个值,则返回对应的这个值
- 使用 K 来定义元组中所有的值(不重复,其结果为
type Deduplication<
T extends unknown[],
K = "",
R extends unknown[] = []
> = T extends [infer A, ...infer B]
? A extends K
? Deduplication<B, K, R>
: Deduplication<B, K | A, [...R, A]>
: R extends [infer U]
? U
: R;
完整示例
type Deduplication<
T extends unknown[],
K = "",
R extends unknown[] = []
> = T extends [infer A, ...infer B]
? A extends K
? Deduplication<B, K, R>
: Deduplication<B, K | A, [...R, A]>
: R extends [infer U]
? U
: R;
type Merged<
R extends Record<string, unknown[]>,
K extends keyof R,
V
> = V extends ""
? Merged<R, K, true>
: Omit<R, K> & Record<K, R[K] extends unknown[] ? [...R[K], V] : [V]>;
type ParserHelper<
T extends string,
R extends Record<string, unknown[]> =
> = T extends `$infer A&$infer B`
? A extends `$infer K=$infer V`
? ParserHelper<B, Merged<R, K, V>>
: ParserHelper<B, Merged<R, A, true>>
: T extends `$infer K=$infer V`
? Merged<R, K, V>
: T extends ""
? R
: Merged<R, T, true>;
type Parser<T extends Record<string, unknown[]>> =
[K in keyof T]: Deduplication<T[K]>;
;
type QueryStringParser<T extends string> = Parser<ParserHelper<T>>;
测试
type A =
QueryStringParser<"a=&a=1&a=1&a=1&b=2&c=3&a=1&b=2&c=3&a=1&b=2&c=3&c=3&a=&a=1&b=5&x=12&xxx&aaa&bbb">;
// type A =
// a: [true, '1']
// b: ['2', '5']
// c: '3'
// x: '12'
// xxx: true
// aaa: true
// bbb: true
//
type B = QueryStringParser<"aaasad">;
// type B = aaasad: true
以上是关于TypeScript 杂记八 《Query String Parser》的主要内容,如果未能解决你的问题,请参考以下文章
TypeScript 杂记八 《Query String Parser》
TypeScript 杂记九 《Integers Comparator》
TypeScript 杂记九 《Integers Comparator》