In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly explains "what are the advanced types of TypeScript and how to use them". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Now let the editor take you to learn "what are the advanced types of TypeScript and how to use them?"
Preface
For students who have the foundation of javascript, it is very easy to get started with typescript. As long as you simply master the basic type system, you can gradually transition js applications to ts applications.
/ / jsconst double = (num) = > 2 * num// tsconst double = (num: number): number = > 2 * num
However, as the application becomes more and more complex, it is easy to set some variables to type any, and typescript writes that it becomes anyscript.
Before we can explain advanced types, we need to briefly understand what generics are.
Generics is an important concept in strongly typed languages. Reasonable use of generics can improve the reusability of the code and make the system more flexible. Here is Wikipedia's description of generics:
Generics allow programmers to use types that are specified later when writing code in a strongly typed programming language and specify these types as parameters when instantiated.
Generics are represented by a pair of angle brackets (). The characters in the angle brackets are called type variables, which are used to represent types.
Function copy (arg: t): t {if (typeof arg = 'object') {return json.parse (json.stringify (arg))} else {return arg}}
This type t is not sure when the copy function is not called, and we don't know exactly what type t stands for until we call copy.
Const str = copy ('my name is typescript')
We can see in vs code that the parameters of the copy function and the return value already have a type, that is, when we call the copy function, we assign the type variable t to string. In fact, we can omit the angle brackets when we call copy, and we can determine that t is string through the type derivation of ts.
Advanced type
In addition to basic types such as string, number, and boolean, we should also be aware of some advanced uses in type declarations.
Cross type (&)
To put it simply, cross-type is to merge multiple types into one type. I feel that it is more reasonable to call it "merge type", and its grammatical rules and logic are consistent with the symbols of "and".
T & u
If I now have two classes, a button and a hyperlink, and now I need a button with a hyperlink, I can use a cross type to implement it.
Interface button {type: string text: string} interface link {alt: string href: string} const linkbtn: button & link = {type: 'danger', text:' jump to Baidu', alt: 'jump to Baidu', href: 'http://www.baidu.com'}
Union type (|)
The syntax rules of a federated type are consistent with the symbol of the logical "or", indicating that its type is any one of the multiple types of connections.
T | u
For example, in the previous button component, our type property can only specify a fixed number of strings.
Interface button {type: 'default' |' primary' | 'danger' text: string} const btn: button = {type:' primary', text: 'button'}
Type alias (type)
If the crossover and union types mentioned earlier need to be used in more than one place, you need to declare an alias for both types in the form of type aliases. Type aliases are similar to the syntax for declaring variables, except that you replace const and let with the type keyword.
Type alias = t | u
Type innertype = 'default' |' primary' | 'danger'interface button {type: innertype text: string} interface alert {type: buttontype text: string}
Type index (keyof)
Keyof is similar to object.keys and is used to get the federation type of key in an interface.
Interface button {type: string text: string} type buttonkeys = keyof button// is equivalent to type buttonkeys = "type" | "text"
Let's take the previous button class as an example. The type type of button comes from another class, buttontypes. According to the previous writing, every buttontypes update needs to modify the button class. If we use keyof, we won't have this trouble.
Interface buttonstyle {color: string background: string} interface buttontypes {default: buttonstyle primary: buttonstyle danger: buttonstyle} interface button {type: 'default' |' primary' | 'danger' text: string} / / after using keyof, after buttontypes is modified, the type type will be automatically modified interface button {type: keyof buttontypes text: string}
Type constraint (extends)
The extends keyword here is different from the inheritance function of using extends after class, and the main role of use within generics is to constrain generics. Let's use the copy method we wrote earlier to give another example:
Type basetype = string | number | boolean// indicates that the parameter / / of copy can only be string, number, Boolean, these basic types function copy (arg: t): t {return arg}
If we pass in an object, there will be a problem.
Extends is often used with keyof. For example, we have a method to get the value of an object, but the object is uncertain, so we can use extends and keyof to constrain it.
Function getvalue (obj: t, key: K) {return obj [key]} const obj = {a: 1} const a = getvalue (obj,'a')
The getvalue method here can constrain the value of key based on the parameter obj passed in.
Type mapping (in)
The main function of the in keyword is to do type mapping, traversing the key of existing interfaces or traversing federated types. Let's use the built-in generic interface readonly as an example.
Type readonly = {readonly [p in keyof t]: t [p];}; interface obj {a: string b: string} type readonlyobj = readonly
We can structure this logic by first keyof obj getting a union type'a'|'b'.
Interface obj {a: string b: string} type objkeys ='a' | 'b'type readonlyobj = {readonly [p in objkeys]: obj [p];}
Then p in objkeys executes the logic of foreach once, traversing'a'|'b'
Type readonlyobj = {readonly a: obj ['a']; readonly b: obj ['b'];}
Finally, you can get a new interface.
Interface readonlyobj {readonly a: string; readonly b: string;}
Condition type (u? X: y)
The syntax rules of conditional types are the same as ternary expressions and are often used in cases where the type is uncertain.
T extends u? X: y
The above means that if t is a subset of u, it is type x, otherwise it is type y. Let's use the built-in generic interface extract as an example.
Type extract = t extends u? T: never
If the type in t exists in u, it is returned, otherwise discarded. Suppose we have two classes with three common properties that can be extracted through extract.
Interface worker {name: string age: number email: string salary: number} interface student {name: string age: number email: string grade: number} type commonkeys = extract// 'name' |' age' | 'email'
Tool generics
There are a lot of tool generics built into typesscript. Readonly and extract have been introduced earlier. Built-in generics are defined in typescript's built-in lib.es5.d.ts, so you can use them directly without any dependencies. Let's take a look at some frequently used tool generics.
Partial
Type partial = {[p in keyof t]?: t [p]}
Partial is used to set all properties of an interface to optional state. First, all the properties of the type variable t are fetched through keyof t, then traversed through in, and finally a? is added after the attribute.
When we write a react component through typescript, if all the properties of the component have default values, we can change the attribute values to optional values through partial.
Import react from 'react'interface buttonprops {type:' button' | 'submit' |' reset' text: string disabled: boolean onclick: () = > void} / / change the props properties of button components to optional const render = (props: partial = {}) = > {const baseprops = {disabled: false, type: 'button', text:' hello world', onclick: () = > {},} const options = {. Baseprops,. Props} return ({options.text})}.
Required
Type required = {[p in keyof t] -?: t [p]}
The function of required is just the opposite of partial, that is, it changes all optional attributes in the interface to required. The difference is to change the attributes in partial. Replaced by -?
Record
Type record = {[p in k]: t}
Record accepts two type variables, the type generated by record has an attribute that exists in type k, and the value is type t. One of the puzzling points here is to add a type constraint to type k, extends keyof any, we can first see what keyof any is.
Basically, type k is constrained in string | number | symbol, which happens to be the type of the object's index, that is, type k can only be specified as these types.
We often construct an array of an object in the business code, but the array is not convenient to index, so we sometimes take out a field of the object as an index and construct a new object. Suppose there is an array of merchandise list, in order to find the merchandise named "Daily Nuts" in the merchandise list, we usually find it by traversing the array, which is more tedious. For convenience, we will rewrite this array into an object.
Interface goods {id: string name: string price: string image: string} const goodsmap: record = {} const goodslist: goods [] = await fetch ('server.com/goods/list') goodslist.foreach (goods = > {goodsmap [goods.name] = goods})
Pick
Type pick = {[p in k]: t [p]}
Pick is mainly used to extract some attributes of the interface. Students who have done the todo tool know that the todo tool will only fill in the description information when editing, and there is only the title and completion status when previewing, so we can use the pick tool to extract two attributes of the todo interface and generate a new type todopreview.
Interface todo {title: string completed: boolean description: string} type todopreview = pickconst todo: todopreview = {title: 'clean room', completed: false}
Exclude
Type exclude = t extends u? Never: t
The role of exclude is just the opposite of the previously introduced extract. If the type in t does not exist in u, it is returned, otherwise it is discarded. Now let's take the previous two classes as examples and look at the results returned by exclude.
Interface worker {name: string age: number email: string salary: number} interface student {name: string age: number email: string grade: number} type excludekeys = exclude// 'name' |' age' | 'email'
The salary that the worker does not exist in the student is taken out.
Omit
Type omit = pick
< t, exclude>The role of omit is just the opposite of pick. Through exclude, you first extract attributes that exist in type t, but k does not exist, and then construct a new type from these attributes. Again, through the previous todo case, the todopreview type only needs to exclude the description attribute of the interface, which is a little more concise than the previous pick.
Interface todo {title: string completed: boolean description: string} type todopreview = omitconst todo: todopreview = {title: 'clean room', completed: false}
At this point, I believe you have a deeper understanding of "what are the advanced types of TypeScript and how to use them?" you might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.