1: typescript introduction and environment construction
1. Introduction to typescript
TS is a superset of JavaScript and can be compiled into pure JavaScript. TS adds many features, such as data types, classes, inheritance and interfaces.
2. Build typescript environment
i. Project environment construction
Install node. JS = > Global typescript: npm i -g typescript
ii. Write a ts file and compile it
Write a. TS file = > command line TSC b.ts = > compile into a JavaScript file.
iii.vscode configuration automatic compilation
Execute instruction in current project
tsc --init
Generate a tsconfig.json file in the project root directory:
Automatically compile, select terminal > Run task > monitor typescript. After that, each time the file is saved, it will be compiled automatically.
2: Data type of typescript
The data types of typescript mainly include:
boolean type
Number type (number)
String type (string)
Array type (array)
tuple type
Enumeration type (enum)
Any type (any)
null and undefined
void type
never type
Format: let variable: type = variable value
1. boolean type
let flag:boolean=[false|true]
2. Number type
let num:number=12
let float:number=12.12
3. String type
let str:string='hello world'
4. Array type
Generic mode
5. Tuple type
Tuple type is a kind of array type. You can specify the type of each element in the array
6. Enumeration type
definition:
enum Enumeration variable name{ Enumeration class name=enum , Enumeration class name 1=Enumeration value 1, ......... }
use
var Variable: enumeration type = enumeration variable name. Enumeration name
or
var variable name = enumeration variable name. Enumeration name
enum flag{ success=1, errorM=-1 } var F:flag=flag.success //var F=flag.success console.log(F);
When single enumeration items are of type number (number by default), if no value is assigned, the index value of the element will be printed. If the element in front of the element has a value, the value printed by the element will be changed to the previous element plus 1
7. Any type (any)
When we get the dom node, we don't know what type to take, so we can use any type
8.null and undefined
i.undefined
The typescript must specify its variable type, otherwise it will report an error. At this time, when we only define no assignment, the variable will also report an error when using the variable
Undefined is provided to solve this problem. If the specified variable is of other types or undefined, no error will be reported if the value is not assigned.
ii.null
It is expressed as null, which is somewhat similar to undefined. A variable may be null or undefined
iii.void type
Represents a method that defines no return value
function fn():void{ console.log('q'); }
In contrast, you can specify the type of return value
function fn():number{ return 1 }
9.never type
Never represents subtypes of other types (including null and underfined), represents values that have never appeared, and is an implicit type. Mainly reflected in
Never type can only be assigned by never type
When num type is declared as above, only one value of number type can be assigned to the variable during assignment. If not, an error will be reported
let nev:never nev:(()=>{ throw new Error('error') })()
The real writing method is as above, but it is not commonly used. It is generally solved by using any or multi type definitions.
3, typescript function
1. Definition of typescript function
There is a return value
function name(params:type):type { return paramType } or let name=function (params:type):type { return paramType }
No return value
function name(params:type):void { } or let name=function (params:type):void { }
4, typescript classes and interfaces
Object: concrete, practical, representing a thing. The attributes and behaviors of an object are encapsulated to form a class.
1.typescript definition class
It uses a new feature of es6: the keyword class
class Person{ }
2. Properties in class
Class has three attributes: variable, constructor and method.
Variables can be divided into public variables, private variables and protection variables
class Person{ public name:string;//If it is a public method, public can be omitted constructor(name:string){ this.name=name } eat(){ console.log('Common method'); } }
i. Instantiation class
Call:
ii.private keyword: static variable
Features: static variables cannot be called directly, but only by providing external access methods,
Benefits: it ensures the security of variables in the class and does not allow external direct access.
class Person{ private name:string; constructor(name:string){ this.name=name } eat(){ console.log('Common method'); } getName(){ return this.name } setName(name:string){ this.name=name } } var p =new person()
Directly through: p.name cannot access this variable, but can only be accessed and modified indirectly through getName/setName
p.getName()
p.setName("little red")
3. Class inheritance: extends
Inheritance can only inherit the public attributes of the parent class, and private attributes cannot be inherited.
Inheritance can only be single inheritance, not multiple inheritance.
Class can only inherit single.
4. Class modifier
typescript provides three modifiers: public, protected, and private
The default is public, which can be omitted during definition.
protected: the modified attribute can only be used within the inheritance system.
private: defined properties can only be used in this class.
5. Static attribute and static method of class: keyword static
In es5, methods and properties are added directly through constructors, which are called static methods and static properties
function Person(){ name:"xiaozhi" setName:()=>{ console.log("Example method") } } Person.age="12" Person.setAge=function(){ console.log('Static method'); } //Static call Person.setAge() Person.age //Instance call var p=new Person() p.setName() p.name
Static methods and static instances in typescript
Differences between static methods and properties and instance methods and properties
Static methods and instances can be called directly through the class name. Instance methods and properties need to be called using the instantiated class name.
Static methods and properties will not disappear after the class is called, but instance methods and properties will.
Define static properties and static methods
class Person{ static name2='xiaozhi'; static run(){ console.log("go"); } } Person.name2 Person.run()
6. Class polymorphism
Polymorphism: the same thing shows different states, indicating polymorphism. The parent class method value definition in polymorphism does not implement the function.
For example, water has three states: solid state, liquid state and gas state, so the parent is water, and the child is water in different states.
Then implement the following code
class water{ name:string; constructor(name:string){ this.name=name } waterState(){} } class Gutai extends water{ constructor(name:string){ super(name) } waterState(){ console.log("I am"+this.name+"water"); } } class Yetai extends water{ constructor(name:string){ super(name) } waterState(){ console.log("I am"+this.name+"water"); } } class Qitai extends water{ constructor(name:string){ super(name) } waterState(){ console.log("I am"+this.name+"water"); } } var gutai=new Gutai('solid state') gutai.waterState() var yetai=new Yetai('liquid state') yetai.waterState() var qitai=new Qitai('Gaseous') qitai.waterState()
7. abstract class: abstract
An abstract class is the base class of a class
For example: everyone has to eat, sleep and breathe. If you extract the breath of eating, sleeping and breathing into a class and modify it with abstract, it will become an abstract class. The only thing is that the abstract class only provides behavior and does not execute behavior. What food you eat, how you sleep, how fast you breathe or how slow you breathe. The abstract class doesn't care. If you inherit me, these behaviors must be.
Abstract classes have the following features:
Abstract classes cannot be instantiated,
Members of abstract classes may not be abstract members, but classes with abstract members must be abstract classes.
Subclasses that inherit abstract classes must override the abstract methods of abstract classes.
A subclass can be an abstract class, indicating that the subclass must have this behavior.
To sum up: an abstract class is a class that provides behavior but does not perform behavior [people are an abstract class and have to eat. Xiaomi is a concrete class (or an abstract subclass, see below). No matter what you eat, you can eat whatever you want, but you must have the behavior of eating].
abstract class Person{ abstract eat():any; } class Xiaoming extends Person{ food:string; constructor(food:string){ super() this.food=food } eat(){ console.log("Xiao Ming can eat and is eating"+this.food); } } var xiaoming=new Xiaoming("Wo Wotou") xiaoming.eat()
Members of abstract classes:
Member variable: it can be either a variable or a constant. When it cannot be modified with abstract (modification cannot initialize the variable)
Member method: it can be either a general method or an abstract method. The general method does not need to be rewritten (it is best to repair the variables that want to access the abstract class)
Constructor: Yes, it is used to initialize member variables.
abstract class Person{ food:string; constructor(food:string){ this.food=food } abstract eat():any; run(){ console.log("Xiao Ming ate while running"+this.food); } } class Xiaoming extends Person{ constructor(food:string){ super(food) } eat(){ console.log("Xiao Ming can eat and is eating"+this.food); } } var xiaoming=new Xiaoming("Chinese Cabbage") xiaoming.eat() xiaoming.run()
5, interface: interface
In typescript, the interface is to restrict json data or expand classes. When restricting json data, it is mainly to restrict object data. The internal data format of standardized object data must be consistent with the interface.
1. Binding effect of interface
a. Interface extends json data (i.e. objects)
interface PersonIf{ name:string; age:number; sex:boolean } function getPerson(obj:PersonIf):string{ return '' } var obejct={ name:'child', age:18, sex:false } getPerson(obejct)
Interpretation: the getPerson function of the above code receives an object of type PersonIf, which is an interface that restricts the format of the transferred object parameters, that is, the obejct object must have the same properties as the interface and will report errors.
It is worth noting that the interface has some attributes, and the object must have them; Objects have attributes, and interfaces are not necessarily mandatory;
interface PersonIf{ name:string; age:number; sex:boolean } function getPerson(obj:PersonIf):string{ return return obj.name+obj.age } var obejct={ name:'child', age:18, } getPerson(obejct)
In general, the json data that is transmitted by the back-end interface may be transmitted to the front end according to the different parameters of the request, and the data can be inconsistent with the field, or what direct parameters are missing. At this time, we can turn the constraint attribute of the interface into an optional value. Use "? Symbol
At this time, there are some attributes in the interface, which do not have to be in the object
interface PersonIf{ name?:string; age?:number; } function getPerson(obj:PersonIf):any{ return obj.name } var obj={ name:'child', } console.log(getPerson(obj));
It is worth noting that when optional parameters are used, there is a return value, and the return type defined by the method should be any, because it is unknown that the name is optional and may be an underfined.
Another way is: (you can see the constraints on the array, which are explained)
b. Interface constrains functions
The interface constrains the function, mainly the parameters and return values of the function
Format:
interface Interface name{ (Parameter name 1:Parameter type 1,Parameter name 2:Parameter type 2,...):return type }
interface PersonIf{ (name:string,age:number):string } let fn:PersonIf=function(name:string,age:number):string{ return name+age } console.log(fn('xiaozhi',18));
c. Interface constraints on arrays (or objects)
Format:
interface Interface name{ [index:number]:Array element type }
If it is an array, the type of index must be number. If it is an object, it can be string (it is not commonly used because the attributes of the object are different in many cases. You can use any to solve it)
Constraint array code:
interface array{ [index:number]:string } let arr:array=['12','34'] console.log(arr);
Constraint object code:
interface obj{ [index:string]:any } let duixiang:obj={ name:'xiaozhi', sex:18, jop:{ p1:'teacher', p2:'parent' } } console.log(duixiang.jop.p1,duixiang.name);
4. Extension of interface to class
It is a bit similar to abstract classes. If a class is compared to a person, it is extracted and encapsulated into an abstract class; What adds to people is the interface.
For example, Zhang San is a person, an abstract class that an individual will inherit (he is not a person if he doesn't eat, sleep or breathe); Zhang San pursues individuality, so he realizes the interface (only red eyebrows and green lipstick have personality). At this time, Wang Wu is also a person and needs the abstract class of successor. However, he does not pursue personality, so he does not implement this interface.
Class implementation interface can be understood like this!!!
interface PersonIf{ name:string; age:number; kouhong():any; } class person implements PersonIf{ name:string; age:number; constructor(name:string,age:number){ this.name=name this.age=age } kouhong(){ console.log(this.name+'this year'+this.age+'year,So put on lipstick'); } } var p=new person("Zhang San",18) console.log(p.kouhong());
Note: Methods in the interface can only be defined and cannot have method bodies; Class implementation interface must override all properties and methods in the interface; Multiple interfaces can be implemented; Interfaces and interfaces can be inherited (generally, multiple implementations are enough, and inheritance is not necessary)
interface PersonIf1{ id:string age:number; kouhong():any; } interface PersonIf2{ name:string; meimao():any; } class person implements PersonIf1,PersonIf2{ id:string; name:string; age:number; constructor(name:string,age:number,id:string){ this.name=name this.age=age this.id=id } kouhong(){ console.log(this.name+'this year'+this.age+'year,So put on lipstick'); } meimao(){ console.log("eyebrow"); } } var p=new person("Zhang San",18,'11111') console.log(p.kouhong());
5. Notes
Class can inherit a class and implement multiple interfaces at the same time
6, Generics
Generics: generics provide a compile time type safety detection mechanism that allows programmers to detect illegal types at compile time The essence of generics is parameterized type, that is, the data type operated on is specified as a parameter.
1. Function generics
There is a requirement that a function can return any type, and any can be used. However, using any does not give up type checking. At this time, generics are needed to solve the problem, so that whatever type is passed in can be put back.
A generic type is a parameterized type that checks the validity of the parameter list.
function fn<T>(name:T):T{ return name } //This call method is quite any //Console.log (FN ('xiaozhi '); //console.log( fn(12)); //console.log( fn(false)); console.log( fn<string>('Xiao Zhi')); console.log( fn<number>(12)); console.log( fn<boolean>(false));
In the above code, < T > represents generic type, T represents generic type name (whatever is passed in), and the generic type here can also be a data type in typescript. In this code, the returned type is generic, and we can also specify the returned type (not generic)
function fn<Y>(name:Y):string{ return 'CODD' } console.log( fn<string>('Xiao Zhi'));
But the following code is wrong
function fn<Y>(name:Y):string{ return name } console.log( fn<string>('Xiao Zhi'));
Because the returned is name, and the type of name is not necessarily string, but may be number.
2. Generic class
There is a requirement to define a class in which the function is to add array elements. It is required that only data of the same data type can be added.
class AddArray<T>{ array:T[]=[]; add(item:T):void{ this.array.push(item) } getArray():any{ return this.array } } var m=new AddArray<string>() m.add('xiozhi') m.add('xiaolei') m.getArray() console.log(m.getArray()); var m2=new AddArray<number>() m2.add(12) m2.add(13) console.log(m2.getArray());
3. Generic interface
i. Function generic interface of generic interface
As the name suggests, it is to load generics on functions in the interface
interface DataInterface{ <T>(str:T):T } var getData:DataInterface=function<T>(name:T):T{ return name } console.log(getData("xiaozhi"));
ii. Generic interface
As the name suggests, you define generics on interfaces.
interface DataInterface<T>{ (str:T):T } function fn<T>(name:T):T{ return name } var getData:DataInterface<string>=fn var getData1:DataInterface<number>=fn console.log(getData("Xiaobai")); console.log(getData1(12));
The generic type is directly specified at the time of definition to simplify the writing method (the function is called only once)
interface DataInterface<T>{ (str:T):T } var getData:DataInterface<string>=function<T>(name:T):T{ return name } console.log(getData("Xiaobai"));
7, typescript modularization
The JavaScript modularization method is used, the module content is exposed by export, and the exposed data is introduced by import.
Create the following file
Write to each file:
user.ts
import userImp from './userImp' class User implements userImp{ name:string age:number constructor(name:string,age:number){ this.name=name this.age=age } getName():string|undefined{ return this.name } setName(name:string):void{ this.name=this.name } getAge():number|undefined{ return this.age } setAge(age:number){ this.age=age } } export default User
userImp.ts
interface userImp{ name:string age:number } export default userImp
index.ts
import User from './user' var user= new User('XIAOHZI',18) console.log(user.age); console.log(user.name);
Because modular programming is compiled into JS and cannot be run by the browser, you need to run jindex.js file through node
1. Namespace
When writing typescript, when there are many classes or variables defined, it may lead to naming conflicts. At this time, we can use namespaces to separate the code and avoid naming conflicts.
namespace space name {........}
In the namespace, you need to export the content to be exported through export.
namespace A{ export class a{ name:string|undefined getName():any{ console.log(this.name); return this.name } } } namespace B{ export class a{ name:string|undefined getName():any{ console.log(this.name); return this.name } } } var Aa=new A.a() var Ba=new B.a
If you want to modularize the namespace, you also need to use export to export the space
export namespace A{ export class a{ name:string|undefined getName():any{ console.log(this.name); return this.name } } }
8, Decorator
Decorator is a method that can inject content into a class, method, attribute and parameter to expand its function.
Mode of use
@Decorator name (param:any) {...}
Receive a parameter that represents the current class, method, property or parameter.
Main: to support decorators, you need to open them in the ts configuration file:
1. No reference decorator
The parameterless decorator params is the class itself
function logDom(params:any){ //param represents the class itself // Adds a property to the current class params.protoType.age='12' // Add method to class params.protoType.getAge=function(){ console.log("11"); } } @logDom class Dome{ constructor(){} show():void{ console.log("Tired"); } } var dome:any=new Dome() console.log(dome.age); dome.getAge()
2. Parametric decorator: returns a function
params of the parameter decorator represents the passed in parameters, and target represents the class itself.
function logDom(params:any){ //param represents the class itself // Adds a property to the current class console.log(params) return function(target:any){ target.protoType.age='12' // Add method to class target.protoType.getAge=function(){ console.log("11"); } } } @logDom("Hello") class Dome{ constructor(){} show():void{ console.log("Tired"); } } var dome:any=new Dome() console.log(dome.age); dome.getAge()
Class decorators can also modify constructors and methods by overloading
function decorateDome(target:any){ return class extends target{ url:any='Hello' getUrl(){ console.log("It is bad"); } } } @decorateDome class Dome{ url:string|undefined; constructor(){ this.url="I am a url" } getUrl(){ console.log(this.url); } } var dome=new Dome() console.log(dome.url,); dome.getUrl()
3. Attribute decorator
One more function returned by the property decorator represents the property
function decorateDome(params:any){ return function(target:any,atrr:any){ target[atrr]=params } } class Dome{ @decorateDome("Attribute decorator") url:string|undefined; constructor(){ // this.url = "I am a url" } getUrl(){ console.log(this.url); } } var dome=new Dome() console.log(dome.url);
4. Method decorator
The function of the method decorator can be used to monitor, modify or replace the definition of the method
Three parameters need to be passed in when the method decorator runs
For static members, it is the constructor of the class, and for instance members, it is the prototype of the class
Member's name
Member's attribute descriptor
function decorateDome(params:any){ return function(target:any,methodName:any,desc:any){ console.log(params); console.log(target); console.log(methodName); console.log(desc); } } class Dome{ url:string|undefined; constructor(){ // this.url = "I am a url" } @decorateDome("Attribute decorator") getUrl(){ console.log(this.url); } } var dome=new Dome()
You can see that target is the class itself, methodName is the method name, desc is the expression of the method, and value is the method itself
a. Replace method with decorator
function decorateDome(params:any){ return function(target:any,methodName:any,desc:any){ desc.value=function(...args:any[]){ console.log(args); } } } class Dome{ url:string|undefined; constructor(){ } @decorateDome("Attribute decorator") getUrl(){ console.log(this.url); } } var dome=new Dome() dome.getUrl("Hello","haha")
At this time, we can see that the method has been replaced, but in many cases, we need to modify the method rather than replace it. At this time, we can use apply to modify the function
function decorateDome(params:any){ return function(target:any,methodName:any,desc:any){ var cMethod=desc.value desc.value=function(...args:any[]){ console.log(args); cMethod.apply(target,args) } } } class Dome{ url:string|undefined; constructor(){ // this.url = "I am a url" } @decorateDome("Attribute decorator") getUrl(){ console.log("I feel OK"); } } //var dome=new Dome() var dome:any=new Dome() dome.getUrl("Hello","haha")
5. Method parameter decorator
Function: when the function is called, use the method decorator to add some properties or methods to the class prototype.
Format:
return function(target:any,methodName:any,paramsIndex:any){ ... }
paramsIndex: indicates the index of the parameter
function decorateDome(params:any){ return function(target:any,methodName:any,paramsIndex:any){ console.log(paramsIndex); target.apiUrl="Ha ha ha" } } class Dome{ url:string|undefined; constructor(){ // this.url = "I am a url" } getUrl(@decorateDome("hello") name:any){ } } var dome:any=new Dome() dome.getUrl("Hello") console.log(dome.apiUrl);
6. Execution sequence of decorator
Attribute decorator > method decorator > method parameter decorator > class decorator
If there are multiple decorators of the same kind, the execution sequence is from bottom to top, right to left.