当前位置:网站首页>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
边栏推荐
- Leetcode48. Rotate image
- Rhcsa day 9
- [untitled]
- Rhcsa12
- Button wizard business running learning - commodity quantity, price reminder, judgment Backpack
- [Galaxy Kirin V10] [desktop] can't be started or the screen is black
- [200 opencv routines] 218 Multi line italic text watermark
- [Galaxy Kirin V10] [desktop] login system flash back
- Check 15 developer tools of Alibaba
- Jianzhi offer 04 (implemented in C language)
猜你喜欢
Two way process republication + routing policy
如果不知道這4種緩存模式,敢說懂緩存嗎?
[Galaxy Kirin V10] [desktop] FTP common scene setup
Basic principle of servlet and application of common API methods
From programmers to large-scale distributed architects, where are you (2)
OSPF summary
leetcode842. Split the array into Fibonacci sequences
Work order management system OTRs
OSPF comprehensive experiment
[Galaxy Kirin V10] [server] system partition expansion
随机推荐
OSPF comprehensive experiment
Ruby time format conversion strftime MS matching format
RHCE - day one
leetcode842. Split the array into Fibonacci sequences
Write a program to define an array with 10 int elements, and take its position in the array as the initial value of each element.
[Galaxy Kirin V10] [server] system partition expansion
Three schemes of ZK double machine room
【Day2】 convolutional-neural-networks
Static comprehensive experiment ---hcip1
Four characteristics and isolation levels of database transactions
Container cloud notes
20 minutes to learn what XML is_ XML learning notes_ What is an XML file_ Basic grammatical rules_ How to parse
How to use diff and patch to update the source code
[Galaxy Kirin V10] [server] set time synchronization of intranet server
[Galaxy Kirin V10] [server] NFS setup
The most detailed teaching -- realize win10 multi-user remote login to intranet machine at the same time -- win10+frp+rdpwrap+ Alibaba cloud server
Recursive method to achieve full permutation (C language)
Press the button wizard to learn how to fight monsters - identify the map, run the map, enter the gang and identify NPC
[Galaxy Kirin V10] [server] iSCSI deployment
Introduction to extensible system architecture