当前位置:网站首页>Pre knowledge reserve of TS type gymnastics to become an excellent TS gymnastics master
Pre knowledge reserve of TS type gymnastics to become an excellent TS gymnastics master
2022-07-07 10:29:00 【Front end technology station】
TS Type gymnastics pre knowledge reserve
If you are learning TS, But like me, I just stay in defining types , Definition interface
/type
At the level of , Don't miss this gymnastics type exercise ! type-challenges
When writing this article, I only finished the medium-level questions of gymnastics type ( also 2-3 Tao is not completely solved )
More interview question banks
Look at the front-end interview question bank
Simply build a question making environment
I like to make a copy of one question , So I clone A copy of type-challenges. And then in type-challenges Created a new folder (my-type-challenges), It's dedicated to TS Artistic Gymnastics
Every time you want to do a question, you just need to remember the number , For example, the first question 13-helloword
. Just input
npm run copy 13
The detailed script is in Jioho/my-type-challenges. After writing the script , You can write code happily
Basic grammar of gymnastics introduction
The following contents are purely personal opinions , Please point out any mistakes or misunderstandings
Although I say TS Turing Complete ( If a computing system can calculate every Turing computable function , Then this system is Turing complete )
however TS There is not so much grammar , such as if,switch,return And so on. .
TS The most used are Ternary operator
, Judge equal
, Array
, recursive
Some skills will be introduced one by one later
TS Built in advanced types ( Built in Gymnastics )
The first step to getting started is to look at the documentation ( Although I don't like watching , Look not to understand ), But you still need to have a basic understanding utility-types
The current built-in method is as follows :
--- | --- | --- | --- |
---|---|---|---|
Partial<Type> | Required<Type> | Readonly<Type> | Record<Keys, Type> |
Pick<Type, Keys> | Omit<Type, Keys> | Exclude<UnionType, ExcludedMembers> | Extract<Type, Union> |
NonNullable<Type> | Parameters<Type> | ConstructorParameters<Type> | ReturnType<Type> |
InstanceType<Type> | ThisParameterType<Type> | OmitThisParameter<Type> | ThisType<Type> |
Uppercase<StringType> | Lowercase<StringType> | Capitalize<StringType> | Uncapitalize<StringType> |
For example, take one that may be used more in the follow-up :
Pick Method
Official website demo:
interface Todo { title: string;
description: string;
completed: boolean;
}type TodoPreview = Pick<Todo, "title" | "completed">;const todo: TodoPreview = { title: "Clean room", completed: false,
};
Pick The function of is from an object , Select the required fields , For instance from TODO Only take out title
and completed
If there is no type of gymnastics ,TodoPreview You have to define an additional type
interface TodoPreview { title:string;
completed: boolean;
}
I encountered this situation in a previous hand training project , Obviously, they are all fields on the same object , In order to adapt to different scenes , Just define a lot of subordinate fields , The key is if you want to change a type , We have to change all of them .. If there is Pick It's all done , Whatever you want pick what
Want to see Pick The implementation is also simple , Pick up any one of them type, Hold down ctrl+ Click on Pick You can see that Pick Realization
The code implementation is as follows :
/**
* From T, pick a set of properties whose keys are in the union K
*/type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
But the first time I saw this code , extends
, keyof
, in
What are these things ? This is the meaning of this article . To look down
Common judgment extends keyword
More interview question banks
Look at the front-end interview question bank
extends Translation means extension
stay TS Acted as if
and stay XXX Within the scope of
One of the functions of .extends It is usually followed by the ternary operator ( There are exceptions. )
Take up a Son
type mytype1 = 1 extends string ? true : false // falsetype mytype2 = '1' extends string ? true : false // truetype mytype2_1 = string extends '1' ? true : false // falsetype mytype3 = mytype1 extends any ? 1 : 2 // 1type mytype4 = [90] extends unknown[] ? true : false // truetype mytype5 = [90] extends string[] ? true : false // false
A few simple examples are given above , A simple explanation :
1 Whether to belong to string type obtain false because 1 It's the number type
'1' Belong to is string Type of The ternary operator is judged as true
string type Belong to '1' Must be false Of ,string Type range ratio '1' Bigger , be not in Belong to The category of the
mytype1 Belong to any The type is right , because any Include everything ~
[90] Is a numerical array , Belong to a
unknown
Array of unknown type , This is also true , Because unknown types also contain numeric typesand [90] It doesn't belong to
string[]
The category of the
extends There are also times when the ternary operator is not connected
For example, write a limit string Type of push Method
type StrPush<T extends string[], U extends string> = [...T, U]type myarr = StrPush<[1, 2, 3], 4>
For example, in this case , It's a direct error . Because I haven't entered StrPush In the judgment of ,T Generics have been constraint by strinig Type ,U Also bound to string type
extends summary
extends stay TS Of
The body of the function
When I was in, I played Judgment category One of the functions ofIn some special places ( For example, when receiving generics , When asserting variable types during function operations ) It plays a role Constraint type The role of
The key of the loop object keyof and in
Just know keyof and in after ,Pick All the keywords of are explained , The first simple question in gymnastics practice MyPick And we're done
It's still up there demo Code
/**
* From T, pick a set of properties whose keys are in the union K
*/type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};interface Todo { title: string;
description: string;
completed: boolean;
}type TodoPreview = Pick<Todo, "title" | "completed">;const todo: TodoPreview = { title: "Clean room", completed: false,
};
extends The above mentioned , Belong to category judgment / Constraint type , In the generic definition <>
It's obviously for constraint types
keyof It can be understood as Put one object
All in key
extracted .
Direct use keyof Extract an object to see the effect :
type TodoKeys = keyof Todo//type TodoKeys = 'title' | 'description' | 'completed'type testkeys = keyof {[k:number]: any; name:string}// type testkeys = number | "name"// Special examples type Mapish = { [k: string]: boolean; name:string };type M = keyof Mapish;// type M = string | number
In the above examples , The first is the best understood , Extract all of key
In the second case ,k As unknown content , extract number As key The scope of the , add "name" So we get number | "name"
A special example is also an example of the official website , Why is there a number type ?
Original words :Note that in this example, M is string | number — this is because JavaScript object keys are always coerced to a string, so obj[0] is always the same as obj["0"].
translate : Please note that , In this example ,M string | number — This is because JavaScript Object keys are always cast to strings , therefore obj[0] Always with obj["0"] identical
combination demo ,K extends keyof T
Which means ,K The value range of parameters can only be Todo Key of ('title' | 'description' | 'completed'
), Limit to string , And this 3 One of the keys / Multiple , Only less , Not much
If it's the following
type Mapish = { [k: string]: boolean; name:string };// K extends keyof Mapish;
K The scope of is string | number type ( Because there is no specific key name , So only No restrictions on specific key names , Only the types are restricted )
Use it like this | Put together ( Or type ) The standard point is called unio Federated data type , Want to cycle these data , You can use in
keyword
go back to demo Explanation
Pick in Generic T What's coming in is Todo type
K extends keyof T
:K Limit to Todo Key value of ( What's coming in is "title" | "completed" Meet the requirements , Because it can only be less but not more )P in k It can be understood as loop
P Will be assigned to title
Then assign a value completed
T[P] Meaning and JS Of [] Same value , obtain T['title'] => string and T['completed'] => completed
{} It will wrap the result of circulation
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};type TodoPreview = Pick<Todo, "title" | "completed">;// TodoPreview = {title:string,completed:boolean}
Pick The implementation of is completed .[P in K]
This cycle and we JS The conventional way of writing is very different , It needs to be digested , Everything else should be easy to understand
Push in , complete Readonly
as everyone knows readonly Just add readonly Parameters can be
The implementation is as follows :keyof Written in brackets , This is allowed , No matter where these keywords are written, as long as they meet the specifications OK, such as MyReadonly2
type MyReadonly<T> = { readonly [P in keyof T]: T[P]
}// This is to paint the snake to the foot , because P It must belong to keyof T Of , It's from keyof T Out of the circulation // But prove keyof It's not just <> Can be used in type MyReadonly2<T> = { readonly [P in keyof T]: P extends keyof T ? T[P] : never}
Small expansion :
'name' extends keyof T ? true : false
Can also judge T Is there any in this generic object name This attribute
keyof and in Summary
keyof
To get all of an objectKey name
, When the key name is a type , Will be upgraded to the corresponding typein
Is for circulation unio Union type data , Most of them are used to regenerate an object in a loop
JS turn TS -- typeof keyword
typeof As from js The world turns into ts The content of the world .
Suppose a scenario , We use one obj Objects are stored as data maps , For example, use a map, Store the status code and return the corresponding msg:
const statusMap = { 200: ' Successful operation ', 404: ' Content not found ', 500: ' operation failed ', 10001: ' Login failure '}var status1 = 200console.log(statusMap[status1]) // Successful operation var status2 = 10001console.log(statusMap[status2]) // Login failure
Similar to the above scenario , At this time of the statusMap
in []
The middle value must be 200,404,500,10001 To meet the requirements , stay TS Naturally, we have to agree status
In this range
If not typeof , We can write something like this TS:
type Status = 200 | 404 | 500 | 10001var status1: Status = 200console.log(statusMap[status1]) // Successful operation var status2: Status = 10001console.log(statusMap[status2]) // Login failure var status3: Status = 301 // Report red (Type '301' is not assignable to type 'Status')
At this time, suppose we add several key values , that TS You have to change it in synchronization ( It's too troublesome ), use typeof
const statusMap = { 200: ' Successful operation ', 404: ' Content not found ', 500: ' operation failed ', 10001: ' Login failure '}type MyStatusMap = typeof statusMap// Now MyStatus The value of will become // type MyStatus = {// 200: string;// 404: string;// 500: string;// 10001: string;// }// Then connect. keyof keyword , Extract the key name of the object type MyStatus = keyof MyStatusMap// type MyStatus = 200 | 404 | 500 | 10001// above 2 One step can be abbreviated to one step type MyStatus2 = keyof typeof statusMap// type MyStatus2 = 200 | 404 | 500 | 10001
This only requires us to change JS The content of ,TS Will automatically get the new object . It's not enough to return the object , Because what we want to constrain above is the incoming key value ( Want to get the key value , Just above learning keyof
keyword ), You can dynamically obtain all the key values that meet the specifications !
typeof Summary
typeof It is a system that can dynamically put JS Object to TS Key words of .
But there are also limited scenarios , That is, the premise of transformation is this part JS yes Fixed content
. Just like an object mapping in the example , That is the fixed content , And then let TS To deduce
And the packaged code cannot exist TS Of , If you want to implement the back-end interface to dynamically return the content in use typeof , It can't be done
Loops of arrays and strings Inference type infer
infer There are many application scenarios
In a nutshell infer Just one. placeholder Tools for , I stand in this position , As for the content of this position infer Not care , It can be left to the later program to judge
Use simple questions 00014-easy-first Let's explain . Achieve one First
Tool type
Usually get the first element , What we think of is T[0]
Of course. TS This grammar is workable
There can be one item in the test case
Equal<First<[]>, never> // Use T[0] This will report an error , because First<[]> The return is undefined
That is, when this element is declared as undefined when , stay TS Most of them use never
Instead of
The correct answer is as follows :
type First<T extends any[]> = T extends [infer F,...infer Rest] ? F : never
Simply put
infer
Must be in TS Used in function operation ( Defining generic <> in Out of commission , and extends Can )infer Can cooperate with ... Carry out operations
T extends [infer F,...infer Rest]
The expression means T extends [F,...Rest The remaining values ].T There must be an attribute
F
Array of ,...Rest
It's the rest , not essential...infer Rest
Is to remove F Other elements are being collected into an array ( This is ES6 The knowledge of the )infer F
It means , I take F In this array placeholder , The contents of the first item of the array , Is being F Account for the
Return to the topic , We want to take the first item , So direct return F type
If T It's an empty array , that extends That step is judged to fail , The natural return is never, Meet the requirements of test cases .
infer Other wonderful uses of
infer It can also traverse strings
Like a The need to cut strings into arrays :
type Split<T extends string, U extends unknown[] = []> =
T extends `${infer F}${infer Rest}` ? Split<Rest, [...U, F]> : Utype testSplit = Split<'123456'>// type testSplit = ["1", "2", "3", "4", "5", "6"]
among ${infer F}${infer Rest}
It means ,F Occupy the first character ,Rest Occupy the remaining characters , Because it doesn't exist in the string ...
The concept of , therefore Rest Basically, it occupies the remaining characters
A test example like this , Altogether 3 Placeholders ,
type testInfer<T extends string> = T extends `${infer F}${infer S}${infer R}` ? [F, S, R] : Ttype testInfer1 = testInfer<'123456'>// According to the characteristics of placeholders , front F and S To occupy separately 2 Characters , Give the rest R Occupied // type testInfer1 = ["1", "2", "3456"]// Make a little change , stay S Add a... After the placeholder 5type testInfer2<T extends string> = T extends `${infer F}${infer S}5${infer R}` ? [F, S, R] : Ttype testInfer3 = testInfer<'123456'>// F Occupy the first character = 1// S occupy 2-4, Because in R There was one before 5, therefore S Represents the beginning of the second character to 5 All characters of // that R It's from 5 Start , To the end , So the results are as follows :// type testInfer1 = ["1", "234", "6"]
There are many more exercises that will be used later infer , So first understand infer placeholder The characteristics of
infer Summary
infer Equivalent to a keyword occupying a position , Copy the occupied position to the corresponding operation variable .
For arrays or other types , Can also be used ... Sum up all the positions to form an array
For strings, this does not exist ... To extend the operator , As long as the front occupies a position , The remaining characters will be replaced by the second placeholder
Array usage
An array is TS A very important characteristic of gymnastics , Because in TS There is no concept of addition and subtraction in gymnastics , The operation of addition and subtraction is indispensable in practical operation , Including getting length and so on .
So the array also acts as Counter The role of . There is another very useful trick about array counters , So useful that I think I can write a separate article to analyze it in detail , Now let's briefly introduce the functions of arrays
Let's start with a simple question , Learn the basic properties and usage of arrays 00018-easy-tuple-length
The title gives 2 An array , It was used as const
. We need to find this 2 The length of an array
const tesla = ['tesla', 'model 3', 'model X', 'model Y'] as constconst spaceX = ['FALCON 9', 'FALCON HEAVY', 'DRAGON', 'STARSHIP', 'HUMAN SPACEFLIGHT'] as consttype teslaLength = Length<typeof tesla>type spaceXLength = Length<typeof spaceX>// answer :type Length<T extends readonly any[]> = T['length']
Is it simple ?! T['length']
Finished ~
So a very important feature of arrays is , He has length
attribute .
Want to use
length
Premise of attribute :T extends any[]
T The range of types , It must be an array ,any[]
perhapsunknown[]
. Will do , It's an array anyway , There islength
attribute .
Based on this problem of finding length , Extend the , seek 2 The combined length of arrays
type MergeArray<T extends readonly any[],U extends readonly any[]> = [...T,...U]['length']type arrLength = MergeArray<typeof tesla, typeof spaceX> // 9
Let's have a little interesting topic to experience the role of arrays Questions with medium difficulty 05153-medium-indexof
Achieve one indexOf( There is another point to pay attention to in the original question, which is what we need to pay attention to when judging the type , I will explain later in this article , Now let's look at the simplest implementation ):
Since we need to calculate the index position , Naturally, it involves a Counter The problem of , Look at the answers below
type numberIndex = IndexOf<[1, 2, 3], 1> // The answer you need is 0type numberIndex2 = IndexOf<[1, 2, 3], 99> // The answer you need is -1type numberIndex3 = IndexOf<[1, 2, 3], 1> // The answer you need is 0// The initial template given by the title ( Missing counter )// type IndexOf<T extends unknown[],U> = any// For these missing parameters , We can completely fill in a parameter by ourselves , And supplement the default value type IndexOf2<T extends unknown[], U, C extends 1[] = []> =
T extends [infer F, ...infer Rest] ?
(F extends U ? C['length'] : IndexOf<Rest, U, [...C, 1]>) : -1
The explanation part :
Because the template given by the title lacks a counter , We can add one C Variable , And the default assignment is
[]
.As long as there is a default value , It is not required , If it is not required, the test case will not report an error
T extends and infer Some of them have been explained , If T Not satisfied with at least one
F
When , explain T The array is empty , When it is empty, it means that the result can be obtainedT It's empty , The data has not been matched , Press indexOf The method of should be to return -1
T If it meets at least one
F
Variable requirements , JudgeF
With the incomingU
Data comparison , If the same, return the length of the current counter ( That is, the index to be calculated )C['length']
If it doesn't fit , take
Rest
The array continues to loop ( Recursively call IndexOf), meanwhile When calling recursively C It becomes[...C,1]
The array length is incremented 1
[...C,1]
The role of , Is to keep the contents of the original array , Adding a 1, Make the original array length + 1 Counter The effect is achieved
Through a simple expansion operator , Add a 1 Make the length of the array constantly change . Reach the counter / The effect of addition
For example, in the first place. 4182 In the title of , There needs to be a Fibonacci sequence
. The characteristic of Fibonacci sequence is n = (n-1)+(n-2)
. How to realize this addition ? In terms of code, it's [...(N-1),...(N-2)].( It doesn't matter if you don't understand , There will be a detailed article later )
Array summary
As long as the corresponding type extends [] Words , You can use ['length'] Property to get the length
Arrays in gymnastics not only act as arrays , It also acts as Counter and Add implementation The role of , Usage is ever-changing
The accumulation of arrays depends on
Recursive method
The implementation of the , In each recursive process, a new length is passed into the new method ( But recursion is easy to cause memory overflow , such as 02257-medium-minusone This question ). Need a more advanced skill to deal with
as keyword
When explaining arrays above, I saw as const
Appearance , By the way as
stay TS In the use ,as It's just one. Assertion
Let's imagine a scenario like this , There is a variable todo , Set up in order to Todo type , There are corresponding properties
Then... Of a function side effect , Led to my todo Become a string type ( The actual code should avoid this side effect function )
but It just happened , And you can't change , By this time todo Should be string type .todo You also need to call a method , Need to stirng Type of function todoFn(str:string){}
. At this time, it is directly transmitted todo I'm sure there will be an error , The type does not conform to
The solution is todoFn(todo as string)
. It will be easier to understand by looking at the code screenshot below
After I concluded that this type is xxx Type can be used
as
keyword ( Of course, it is not recommended to use ), Try to use TS Type derivation of
stay TS When defining the type of ,as It has other meanings
Like this one
const teslaConst = ['tesla', 'model 3', 'model X', 'model Y'] as const// const teslaConst: readonly ["tesla", "model 3", "model X", "model Y"]// use var Variables and const The derivation is the same , But it will leave code hidden trouble , Not recommended var teslaConst2 = ['tesla', 'model 3', 'model X', 'model Y'] as const// var teslaConst: readonly ["tesla", "model 3", "model X", "model Y"]const tesla = ['tesla', 'model 3', 'model X', 'model Y']// const tesla: string[]
The difference is obvious ,as const Will take out all the values , And become readonly. because const It's really a read-only tag .
however TS Don't eat js Variable type , So I have to pass
as const
To tell TS, I assert that this is a const Array , The elements inside will not be changed , You can traverse the values here
useless as const I only think it's a string[] Array of . This is a big difference
Last
TS The pre knowledge reserve of type gymnastics is probably introduced extends
,infer
,typeof
,keyof and in
, Use of arrays
,as keyword
After understanding the functions of these keywords , complete TS Not to mention the medium difficulty of gymnastics practice !( At least finish 80% No problem with your title ), The rest 20% Still need to learn more TS Gymnastics skills
This feeling is like if you want to untie a One variable quadratic equation Before , You have to learn the usage and rules of addition, subtraction, multiplication and division . The above introduction is the basic rules of addition, subtraction, multiplication and division , Later, we need to learn more skillful skills to complete more complex TS Artistic Gymnastics
More interview question banks
边栏推荐
- 小程序跳转H5,配置业务域名经验教程
- 关于hzero-resource报错(groovy.lang.MissingPropertyException: No such property: weight for class)
- Differences between MCU and MPU
- MCU is the most popular science (ten thousand words summary, worth collecting)
- 2022.7.3DAY595
- 学习记录——高精度加法和乘法
- Postman interface test IV
- Leetcode exercise - 113 Path sum II
- Some properties of leetcode139 Yang Hui triangle
- Serial communication relay Modbus communication host computer debugging software tool project development case
猜你喜欢
JMeter loop controller and CSV data file settings are used together
Some properties of leetcode139 Yang Hui triangle
【acwing】789. 数的范围(二分基础)
Postman interface test IV
求方程ax^2+bx+c=0的根(C语言)
5个chrome简单实用的日常开发功能详解,赶快解锁让你提升更多效率!
How to cancel automatic saving of changes in sqlyog database
IO模型复习
Adb 实用命令(网络包、日志、调优相关)
The Hal library is configured with a general timer Tim to trigger ADC sampling, and then DMA is moved to the memory space.
随机推荐
Experience sharing of software designers preparing for exams
STM32 Basics - memory mapping
Postman interface test VII
HDU-2196 树形DP学习笔记
反射效率为什么低?
STM32 ADC和DMA
CONDA creates virtual environment offline
LeetCode 练习——113. 路径总和 II
使用U2-Net深层网络实现——证件照生成程序
[email protected]能帮助我们快速拿到日志对象
JMeter about setting thread group and time
High number_ Chapter 1 space analytic geometry and vector algebra_ Quantity product of vectors
【acwing】789. 数的范围(二分基础)
施努卡:机器视觉定位技术 机器视觉定位原理
Encrypt and decrypt stored procedures (SQL 2008/sql 2012)
[牛客网刷题 Day5] JZ77 按之字形顺序打印二叉树
HAL库配置通用定时器TIM触发ADC采样,然后DMA搬运到内存空间。
P2788 数学1(math1)- 加减算式
The story of Plato and his three disciples: how to find happiness? How to find the ideal partner?
When there are pointer variable members in the custom type, the return value and parameters of the assignment operator overload must be reference types