当前位置:网站首页>TS type gymnastics: illustrating a complex advanced type
TS type gymnastics: illustrating a complex advanced type
2022-07-01 03:50:00 【Xianling Pavilion】
Today, let's do a difficult gymnastics , It uses pattern matching 、 structure 、 Recursive equivalent routine , It is very helpful to improve the level of type programming .
The advanced types we want to implement are as follows :

Its type parameter is the parameter string query string, The parsed parameter object will be returned , If you have a parameter with the same name , Will merge the values .
Don't worry about realizing , Let's first review the relevant types of gymnastics :
Type gymnastics foundation
Pattern matching
Pattern matching refers to matching a pattern type with a type to extract some of its types to infer Declared local variables .
Like extracting a=b Medium a and b:

This pattern matching routine is in the array 、 character string 、 Functions and other types have many applications .
structure
Mapping types are used to generate index types , The index or index value can be modified during the generation process .
For example, specify key and value To generate an index type :

recursive
TypeScript Advanced types support recursion , It can handle the problem of uncertain quantity .
For example, the inversion of an indefinite length string :
type ReverseStr<
Str extends string,
Result extends string = ''
> = Str extends `${
infer First}${
infer Rest}`
? ReverseStr<Rest, `${
First}${
Result}`>
: Result;
Copy code

Learn about pattern matching 、 structure 、 After what recursion is , You can start implementing this complex high-level type ParseQueryString 了 :
Thought analysis
Suppose there is one query string: a=1&a=2&b=3&c=4.
We should first divide it into 4 part : That is to say a=1、a=2、b=3、c=4. This is extracted through the pattern matching mentioned above .
Each part can be further processed , Extract key value Constructed as an index type , such as a=1 Can be extracted by pattern matching a、1, Then construct the index type {a: 1}.
That's it 4 Index types {a:1}、{a:2}、{b:3}、{c:4}.
Just combine it into one , When merging, if there are the same key Value , Put it in the array .
The final index type is generated :{a: [1,2], b: 3, c: 4}
The whole process is like this :

The first step is not to know how many a=1、b=2 such query param, So we need to recursively do pattern matching to extract .
This is the implementation idea of this advanced type .
Let's write about it in detail :
Code implementation
We implement it in the order shown in the figure above , First extract query string Each of them query param:

query param The quantity is uncertain , So use recursion :
type ParseQueryString<Str extends string>
= Str extends `${
infer Param}&${
infer Rest}`
? MergeParams<ParseParam<Param>, ParseQueryString<Rest>>
: ParseParam<Str>;
Copy code
Type parameter Str For pending query string.
Extract the first one through pattern matching query param To infer Declared local variables Param in , The rest of the string is put in Rest in .
use ParseParam To deal with it Param, The rest of the recursive processing , Finally, combine them , That is to say MergeParams<ParseParam<Param>, ParseQueryString> .
If the pattern match does not meet , Explain that there is still one last query param 了 , Also used ParseParam Handle .
Then implement each one separately query param Of parse:

This is pattern matching extraction key and value, Then construct an index type :
type ParseParam<Param extends string>
= Param extends `${
infer Key}=${
infer Value}`
? {
[K in Key]: Value }
: {
};
Copy code
Here, the syntax of mapping type is used to construct index type .
Let's test this first ParseParam:

Finish each query param The analysis of , Then merge them together :

The merged part is MergeParams:
type MergeParams<
OneParam extends object,
OtherParam extends object
> = {
[Key in keyof OneParam | keyof OtherParam]:
Key extends keyof OneParam
? Key extends keyof OtherParam
? MergeValues<OneParam[Key], OtherParam[Key]>
: OneParam[Key]
: Key extends keyof OtherParam
? OtherParam[Key]
: never
}
Copy code
The merging of the two index types also requires the construction of a new index type using the syntax of the mapping type .
key Is taken from both, that is key in keyof OneParam | keyof OtherParam.
value There are two situations :
If both index types exist key, Merge , That is to say MergeValues.
If only one of the index types has , Then take its value , That is to say OtherParam[key] perhaps OneParam[Key].
When merging , If both are the same, either one will be returned , If it's not the same , Merge it into an array and return , That is to say [One, Other]. If it was an array , That is the merging of arrays [One, …Other].
type MergeValues<One, Other> =
One extends Other
? One
: Other extends unknown[]
? [One, ...Other]
: [One, Other];
Copy code
Under test MergeValues:

such , We have implemented the whole advanced type , Overall test :

This case applies recursion synthetically 、 Pattern matching 、 Structured routine , It's more complicated .
You can look at the complete code with reference to this figure :

type ParseParam<Param extends string> =
Param extends `${
infer Key}=${
infer Value}`
? {
[K in Key]: Value
} : {
};
type MergeValues<One, Other> =
One extends Other
? One
: Other extends unknown[]
? [One, ...Other]
: [One, Other];
type MergeParams<
OneParam extends object,
OtherParam extends object
> = {
[Key in keyof OneParam | keyof OtherParam]:
Key extends keyof OneParam
? Key extends keyof OtherParam
? MergeValues<OneParam[Key], OtherParam[Key]>
: OneParam[Key]
: Key extends keyof OtherParam
? OtherParam[Key]
: never
}
type ParseQueryString<Str extends string> =
Str extends `${
infer Param}&${
infer Rest}`
? MergeParams<ParseParam<Param>, ParseQueryString<Rest>>
: ParseParam<Str>;
type ParseQueryStringResult = ParseQueryString<'a=1&a=2&b=2&c=3'>;
Copy code
summary
We first reviewed 3 The routines of three types of gymnastics :
Pattern matching : A type matches a pattern type , Extract some of these types to infer Declared local variables
structure : Construct a new index type by mapping the syntax of the type , The index and value can be modified during construction
recursive : When dealing with types with uncertain quantities , You can only process one at a time , Hand over the rest to do
Then use these routines to achieve a ParseQueryString Complex advanced types .
If you can implement this high-level type independently , It shows that you have a good grasp of the routines of these three types of gymnastics .
Last
If you think this article is of little help to you , Point a praise . Or you can join my development communication group :1025263163 Learn from each other , We will have professional technical questions and answers
If you think this article is useful to you , Please give our open source project a little bit star:http://github.crmeb.net/u/defu Thank you for !
PHP Learning manual :https://doc.crmeb.com
Technical exchange forum :https://q.crmeb.com
边栏推荐
- Deep learning | rnn/lstm of naturallanguageprocessing
- Review column - message queue
- 165. 比较版本号
- 5. [WebGIS practice] software operation - service release and permission management
- 206.反转链表
- 205. isomorphic string
- 10、Scanner. Next() cannot read spaces /indexof -1
- Usage of AfxMessageBox and MessageBox
- C语言的sem_t变量类型
- 187. 重复的DNA序列
猜你喜欢

Appium自动化测试基础 — APPium基本原理

Pytorch training deep learning network settings CUDA specified GPU visible

Bilinear upsampling and f.upsample in pytorch_ bilinear

JMeter login failure, extracting login token, and obtaining token problem solving

【TA-霜狼_may-《百人計劃》】1.2.1 向量基礎

MFC window scroll bar usage

C语言的sem_t变量类型
![[ta - Frost Wolf May - 100 people plan] 1.2.1 base vectorielle](/img/94/99090ea91082a385968e071ef3766c.png)
[ta - Frost Wolf May - 100 people plan] 1.2.1 base vectorielle

线程常用方法与守护线程

Use selenium automated test tool to climb the enrollment score line and ranking of colleges and universities related to the college entrance examination
随机推荐
Blueprism registration, download and install -rpa Chapter 1
bootsrap中的栅格系统
214. minimum palindrome string
不同性能测试工具的并发模式
访问阿里云存储的图片URL实现在网页直接预览略缩图而不直接下载
Valentine's Day is nothing.
8. 字符串转换整数 (atoi)
72. edit distance
Appium自动化测试基础--补充:C/S架构和B/S架构说明
[party benefits] jsonobject to string, leave blank
用小程序的技术优势发展产业互联网
[ta- frost wolf \u may- hundred people plan] 2.2 model and material space
【快捷键】
165. compare version numbers
Cygwin的下载和安装配置
6. zigzag transformation
Appium自动化测试基础 — APPium基本原理
[TA frost wolf \u may- hundred talents plan] 1.2.3 MVP matrix operation
431. encode n-ary tree as binary tree DFS
The method to measure the similarity of two vectors: cosine similarity, pytorch calculate cosine similarity: torch nn. CosineSimilarity(dim=1, eps=1e-08)