当前位置:网站首页>TS type gymnastics: illustrating a complex advanced type
TS type gymnastics: illustrating a complex advanced type
2022-07-04 10:36:00 【PHP Development Engineer 】
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
边栏推荐
- VLAN part of switching technology
- Differences among opencv versions
- Es entry series - 6 document relevance and sorting
- Sword finger offer 05 (implemented in C language)
- How to quickly parse XML documents through C (in fact, other languages also have corresponding interfaces or libraries to call)
- Use the data to tell you where is the most difficult province for the college entrance examination!
- Jianzhi offer 04 (implemented in C language)
- 20 minutes to learn what XML is_ XML learning notes_ What is an XML file_ Basic grammatical rules_ How to parse
- Software sharing: the best PDF document conversion tool and PDF Suite Enterprise version sharing | with sharing
- /*The rewriter outputs the contents of the IA array. It is required that the type defined by typedef cannot be used in the outer loop*/
猜你喜欢
Summary of several job scheduling problems
The most detailed teaching -- realize win10 multi-user remote login to intranet machine at the same time -- win10+frp+rdpwrap+ Alibaba cloud server
Realsense of d435i, d435, d415, t265_ Matching and installation of viewer environment
[Galaxy Kirin V10] [server] NUMA Technology
Rhcsa day 10 operation
system design
Add t more space to your computer (no need to add hard disk)
六月份阶段性大总结之Doris/Clickhouse/Hudi一网打尽
Four characteristics and isolation levels of database transactions
PHP code audit 3 - system reload vulnerability
随机推荐
基于线性函数近似的安全强化学习 Safe RL with Linear Function Approximation 翻译 2
System. Currenttimemillis() and system Nanotime (), which is faster? Don't use it wrong!
Si vous ne connaissez pas ces quatre modes de mise en cache, vous osez dire que vous connaissez la mise en cache?
Lavel document reading notes -how to use @auth and @guest directives in lavel
Latex insert picture, insert formula
Realsense d435 d435i d415 depth camera obtains RGB map, left and right infrared camera map, depth map and IMU data under ROS
Use the data to tell you where is the most difficult province for the college entrance examination!
[Galaxy Kirin V10] [server] set time synchronization of intranet server
/*Rewrite the program, find the value of the element, and return the iterator 9.13: pointing to the found element. Make sure that the program works correctly when the element you are looking for does
Service developers publish services based on EDAs
BGP ---- border gateway routing protocol ----- basic experiment
Container cloud notes
uniapp 小于1000 按原数字显示 超过1000 数字换算成10w+ 1.3k+ 显示
From programmers to large-scale distributed architects, where are you (I)
Write a program that uses pointers to set all elements of an int array to 4.18: 0.
Time complexity and space complexity
Software sharing: the best PDF document conversion tool and PDF Suite Enterprise version sharing | with sharing
Delayed message center design
/*The rewriter outputs the contents of the IA array. It is required that the type defined by typedef cannot be used in the outer loop*/
【Day1】 deep-learning-basics