当前位置:网站首页>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
边栏推荐
- 171. Excel 表列序号
- 389. 找不同
- 5. [WebGIS practice] software operation - service release and permission management
- pytorch nn. AdaptiveAvgPool2d(1)
- [ta- frost wolf \u may- hundred people plan] 1.1 rendering pipeline
- 8. 字符串转换整数 (atoi)
- 在线公网安备案保姆级教程【伸手党福利】
- [ta - Frost Wolf May - 100 people plan] 2.3 Introduction aux fonctions communes
- 318. 最大单词长度乘积
- 浏览器顶部loading(来自知乎)
猜你喜欢

How to display scrollbars on the right side of the background system and how to solve the problem of double scrollbars

The problem of integrating Alibaba cloud SMS: non static methods cannot be referenced from the static context

RSN:Learning to Exploit Long-term Relational Dependencies in Knowledge Graphs
![5. [WebGIS practice] software operation - service release and permission management](/img/5d/070e207bd96e60ba1846d644d4fb54.png)
5. [WebGIS practice] software operation - service release and permission management

RSN:Learning to Exploit Long-term Relational Dependencies in Knowledge Graphs

Leetcode 31 next spread, leetcode 64 minimum path sum, leetcode 62 different paths, leetcode 78 subset, leetcode 33 search rotation sort array (modify dichotomy)

TEC: Knowledge Graph Embedding with Triple Context

Millet College wechat scanning code login process record and bug resolution

Grid system in bootstrap

整合阿里云短信的问题:无法从静态上下文中引用非静态方法
随机推荐
Its appearance makes competitors tremble. Interpretation of Sony vision-s 02 products
72. edit distance
[TA frost wolf \u may- hundred talents plan] 1.2.3 MVP matrix operation
30. Concatenate substrings of all words
[JPCs publication] the Third International Conference on control theory and application in 2022 (icocta 2022)
【快捷键】
Usage of AfxMessageBox and MessageBox
TEC: Knowledge Graph Embedding with Triple Context
Jeecgboot output log, how to use @slf4j
Unexpected token o in JSON at position 1 ,JSON解析问题
Explain spark operation mode in detail (local+standalone+yarn)
How to display scrollbars on the right side of the background system and how to solve the problem of double scrollbars
JMeter login failure, extracting login token, and obtaining token problem solving
【TA-霜狼_may-《百人计划》】2.1 色彩空间
【TA-霜狼_may-《百人計劃》】1.2.1 向量基礎
Asgnet paper and code interpretation 2
Blueprism registration, download and install -rpa Chapter 1
205. isomorphic string
Use selenium automated test tool to climb the enrollment score line and ranking of colleges and universities related to the college entrance examination
[TA frost wolf \u may- hundred people plan] 2.3 introduction to common functions