Getting started with typescript
Tip: This article is sorted out according to the typescript tutorial of shangsilicon Valley in station B (Teacher Li Lichao's new TS course)
Video direction of station B:Shang Silicon Valley typescript tutorial (New TS class of Teacher Li Lichao)
preface
- Typescript is a superset of JavaScript.
- It extends JS, introduces the concept of type into JS, and adds many new features.
- TS code needs to be compiled into JS by compiler, and then executed by JS parser.
- TS is fully compatible with JS. In other words, any JS code can be directly used as ts.
- Compared with JS, TS has static types, stricter syntax and more powerful functions; Ts can complete code checking before code execution, reducing the probability of runtime exceptions; TS code can be compiled into any version of JS code, which can effectively solve the compatibility problem of different JS running environments; For the same function, the code quantity of TS is larger than that of JS. However, because the code structure of TS is clearer and the variable type is clearer, TS is far better than JS in the later code maintenance.
Tips: the following is the text of this article. The following cases are for reference
1、 Typescript development environment setup
TypeScript
Installation is required before useNode.js
(make sure the installation is complete)-
use
npm
Global installationtypescript
npm i -g typescript
- Create a
ts
Files, usingtsc
yests
File to compile - Enter command line
- Enter the directory where the TS file is located
- Execute command:
tsc xxx.ts
2、 Basic type
2.1 type declaration
- Type declaration is
TS
A very important feature - Type declarations allow you to specify
TS
Types of variables (parameters, formal parameters) in - After specifying the type, when assigning a value to a variable,
TS
The compiler will automatically check whether the value conforms to the type declaration. If it conforms, it will assign a value. Otherwise, an error will be reported - In short, a type declaration sets the type of a variable so that it can only store values of a certain type
-
Syntax:
Let variable: type; Let variable: type = value; Function fn (parameter: type, parameter: type): type{ ... }
2.2 automatic type judgment
TS
With automatic type judgment mechanism- When a variable is declared and assigned at the same time,
TS
The compiler automatically determines the type of the variable -
So if your variables are declared and assigned at the same time, you can omit the type declaration
2.3 type
type example describe number 1, -33, 2.5 Any number string ‘hi’, “hi”, hi
Arbitrary string boolean true、false Boolean value true or false Literal Itself The value of the restriction variable is the value of the literal any * Any type unknown * Type safe any void Null (undefined) No value (or undefined) never No value Cannot be any value object {name:’Monkey King’} Any JS object array [1,2,3] Any JS array tuple [4,5] Yuanzu, TS new type, fixed length array enum enum{A, B} Enumeration, new types in TS number
let decimal: number = 6; let hex: number = 0xf00d; let binary: number = 0b1010; let octal: number = 0o744; let big: bigint = 100n;
boolean
let isDone: boolean = false;
string
let color: string = "blue"; color = 'red'; let fullName: string = `Bob Bobbington`; let age: number = 37; let sentence: string = `Hello, my name is ${fullName}. I'll be ${age + 1} years old next month.`;
Literal
- You can also use literals to specify the type of a variable. You can use literals to determine the value range of a variable
-
You can use | to connect multiple types (Union types)
let color: 'red' | 'blue' | 'black'; let num: 1 | 2 | 3 | 4 | 5;
any
any
Indicates any type. A variable is set toany
After that, it is equivalent to closing theTS
Type detection of-
use
TS
Not recommended whenany
typelet d: any = 4; d = 'hello'; d = true;
-
If a variable is declared without specifying a type, the TS parser will automatically determine that the type of the variable is
any
(implicitany
)let d; d = 10; d = 'hello'; d = true;
unknown
unknown
Represents a value of unknown typeunknown
In fact, it is a type safe any-
unknown
Variables of type cannot be directly assigned to other variableslet notSure: unknown = 4; notSure = 'hello';
void
-
void
Used to indicate null. Taking a function as an example, it means a function without a return valuelet unusable: void = undefined; function fn(): void{ }
never
-
never
Indicates that the result will never be returnedfunction error(message: string): never { throw new Error(message); }
object
-
object
Represents ajs
object//{} is used to specify which attributes can be included in an object //Syntax: {attribute name: attribute value, attribute name: attribute value} //Add?, after the attribute name?, Indicates that the attribute is optional let b: {name: string, age?: number}; B = {name: 'Sunwukong', age: 18}; //[propname: string]: any indicates any type of attribute let c: {name: string, [propName: string]: any}; C = {name: 'Zhu Bajie', age: 18, gender: 'male'}; let obj: object = {};
array
/*
*Type declaration of array:
*Type []
*Array< type >
* */
//String[] indicates an array of strings
let e: string[];
e = ['a', 'b', 'c'];
//Number[] indicates a numeric value
let f: number[];
let g: Array<number>;
g = [1, 2, 3];
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];
tuple
- Tuples, tuples are arrays of fixed length
/*
*Tuples, tuples are arrays of fixed length
*Syntax: [type, type, type]
* */
let x: [string, number];
x = ["hello", 10];
Enum enumeration
enum Color {
Red,
Green,
Blue,
}
let c: Color = Color.Green;
enum Color {
Red = 1,
Green,
Blue,
}
let c: Color = Color.Green;
enum Color {
Red = 1,
Green = 2,
Blue = 4,
}
let c: Color = Color.Green;
//& indicate simultaneous
let j: { name: string } & { age: number };
J = {name: 'Sunwukong', age: 18};
Type Asserts
- In some cases, the type of variables is very clear to us, but the TS compiler is not clear. In this case, the compiler can be told the type of variables through type assertions. There are two forms of assertions:
/*
-Syntax:
-Variable as type
-< type > variable
- */
s = e as string;
s = <string>e;
- First
let someValue: unknown = "this is a string";
let strLength: number = (someValue as string).length;
-
Second
let someValue: unknown = "this is a string"; let strLength: number = (<string>someValue).length;
Alias for type
type myType = 1 | 2 | 3 | 4 | 5;
let k: myType;
let l: myType;
let m: myType;
k = 2;
3、 Object oriented
3.1 class
For example: you canPerson
Class to create human objects throughDog
Class to create an object for a dog, using theCar
Class to create objects for cars. Different classes can be used to create different objects.
Define class:
Class class name{
Attribute name: type;
Constructor (parameter: type){
this. Attribute name = parameter;
}
Method name (){
....
}
}
Example:
Define class
class Person{
name: string;
age: number;
constructor(name: string, age: number){
this.name = name;
this.age = age;
}
sayHello(){
console. Log ('Hello, I am ${this.name} ');
}
}
Use class
Const P = new person ('sunwukong ', 18);
p.sayHello();
3.2 object oriented features
3.2.1 keywords
- encapsulation
- An object is essentially a container for attributes and methods. Its main function is to store attributes and methods. This is the so-called encapsulation
- By default, the attributes of an object can be modified arbitrarily. To ensure data security, the permissions of attributes can be set in TS
- Read only attribute(
readonly
):
If you add areadonly
, the property becomes read-only and cannot be modified - Attributes in ts have three modifiers:
1.public
(default), which can be modified in classes, subclasses, and objects
2.protected
, which can be modified in class and subclass
3.private
, which can be modified in the class - Example:
-
public
class Person{ public name: string; // Writing or not writing anything is public public age: number; constructor(name: string, age: number){ this. name = name; // Can be modified in class this.age = age; } sayHello(){ console. Log ('Hello, I am ${this.name} '); } } class Employee extends Person{ constructor(name: string, age: number){ super(name, age); this. name = name; // Can be modified in subclasses } } Const P = new person ('sunwukong ', 18); p. Name = 'Zhu Bajie'// Can be modified by objects
-
protected
class Person{ protected name: string; protected age: number; constructor(name: string, age: number){ this. name = name; // Can be modified this.age = age; } sayHello(){ console. Log ('Hello, I am ${this.name} '); } } class Employee extends Person{ constructor(name: string, age: number){ super(name, age); this. name = name; // Can be modified in subclasses } } Const P = new person ('sunwukong ', 18); p. Name = 'Zhu Bajie'// Cannot modify
-
private
class Person{ private name: string; private age: number; constructor(name: string, age: number){ this. name = name; // Can be modified this.age = age; } sayHello(){ console. Log ('Hello, I am ${this.name} '); } } class Employee extends Person{ constructor(name: string, age: number){ super(name, age); this. name = name; // Cannot modify in subclass } } Const P = new person ('sunwukong ', 18); p. Name = 'Zhu Bajie'// Cannot modify
Attribute accessor
- For some properties that you do not want to modify arbitrarily, you can set them to
private
- Set it directly to
private
Will result in properties that can no longer be modified through the object - We can define a set of methods to read and set attributes in a class. The attributes read or set to attributes are called attribute accessors
- The method of reading attributes is called
setter
Method. The method for setting properties is calledgetter
method -
Example:
class Person{ private _name: string; constructor(name: string){ this._name = name; } get name(){ return this._name; } set name(name: string){ this._name = name; } } Const P1 = new person ('monkey King '); console. log(p1.name); // Read the name attribute through getter P1.name ='pig Eight Precepts'// Modify the name attribute through setter
Static properties
- Static attributes (Methods), also known as class attributes. You can use static attributes directly through classes without creating instances
- Use of static attributes (Methods)
static
start -
Example:
class Tools{ static PI = 3.1415926; static sum(num1: number, num2: number){ return num1 + num2 } } console.log(Tools.PI); console.log(Tools.sum(123, 456));
this
In the class, use this to represent the current object
3.2.2 constructor
constructor
Called constructor-
Constructor is called when the object is created
class Dog{ name: string; age: number; //Constructors are called constructors //Constructor is called when the object is created constructor(name: string, age: number) { //In the instance method, this represents the current instance //In the constructor, the current object is the newly created object //You can add attributes to a new object through this this.name = name; this.age = age; } bark(){ //Alert ('woof, woof! '); //This can be used in a method to represent the object that is currently calling the method console.log(this.name); } } Const dog = new dog ('little Black ', 4); Const dog2 = new dog ('xiaobai ', 2); // console.log(dog); // console.log(dog2); dog2.bark();
3.2.3 inherit extensions
(function (){ //Define an animal class class Animal{ name: string; age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } sayHello(){ console. Log ('animal is calling ~ '); } } /* * Dog extends Animal *- at this time, animal is called the parent class and dog is called the child class *- after inheritance is used, the subclass will have all the methods and properties of the parent class *- code common to multiple classes can be written in a parent class through inheritance, *In this way, you only need to write once to make all subclasses have the properties and methods in the parent class at the same time *If you want to add some properties or methods in the subclass that are not in the parent class, just add them directly *- if the same method as the parent class is added to the subclass, the subclass method will overwrite the parent class method *This subclass overrides the form of the parent method, which we call method override * * */ //Define a class that represents a dog //Make dog class inherit animal class class Dog extends Animal{ run(){ console. Log (`${this.name} is running ~~`); } sayHello() { console. Log ('woof woof woof! '); } } //Define a class that represents a cat //Make cat class inherit animal class class Cat extends Animal{ sayHello() { console. Log ('meow meow! '); } } Const dog = new dog ('wangcai ', 5); Const cat = new cat ('mimi ', 3); console.log(dog); dog.sayHello(); dog.run(); console.log(cat); cat.sayHello(); })();
3.2.4 super keyword
(function () { class Animal { name: string; constructor(name: string) { this.name = name; } sayHello() { console. Log ('animal is calling ~ '); } } class Dog extends Animal{ age: number; constructor(name: string, age: number) { //If a constructor is written in a subclass, the constructor of the parent class must be called in the subclass constructor super(name); // Call the constructor of the parent class this.age = age; } sayHello() { //In the method of a class, super represents the parent class of the current class //super.sayHello(); console. Log ('woof woof woof! '); } } Const dog = new dog ('wangcai ', 3); dog.sayHello(); })();
3.2.5 abstract classes
-
with
abstract
The first class is an abstract class(function () { /* *Classes starting with abstract are abstract classes, *Abstract classes are not different from other classes, but they cannot be used to create objects *An abstract class is a class that is specifically used to be inherited * *Abstract methods can be added to abstract classes * */ abstract class Animal { name: string; constructor(name: string) { this.name = name; } //Define an abstract method //Abstract method starts with abstract and has no method body //Abstract methods can only be defined in abstract classes. Subclasses must override abstract methods abstract sayHello():void; } class Dog extends Animal{ sayHello() { console. Log ('woof woof woof! '); } } class Cat extends Animal{ sayHello() { console. Log ('meow meow! '); } } Const dog = new dog ('wangcai '); dog.sayHello(); })();
3.2.6 encapsulation of attributes
(function (){ //Define a class that represents people class Person{ //Ts can add attribute modifiers before attributes /* *The public decorated attribute can access (modify) the default value at any location *Private private attribute, which can only be accessed (modified) within a class *- private properties can be accessed externally by adding methods to the class *The protected contained attribute can only be accessed (modified) in the current class and subclasses of the current class * * */ private _name: string; private _age: number; constructor(name: string, age: number) { this._name = name; this._age = age; } /* *The getter method is used to read properties *The setter method is used to set properties *- they are called accessors for attributes * */ //Define a method to get the name attribute // getName(){ // return this._name; // } // //// define a method to set the name attribute // setName(value: string){ // this._name = value; // } // // getAge(){ // return this._age; // } // // setAge(value: number){ //// judge whether the age is legal // if(value >= 0){ // this._age = value; // } // } //How to set getter methods in TS get name(){ // console. Log ('Get name() executed!! '); return this._name; } set name(value){ this._name = value; } get age(){ return this._age; } set age(value){ if(value >= 0){ this._age = value } } } Const per = new person ('monkey King ', 18); /* *Now the attribute is set in the object. The attribute can be modified at will, *Properties can be modified arbitrarily, which will make the data in the object very unsafe * */ // per. Setname ('pig Eight Precepts'); // per.setAge(-33); per. Name = 'Zhu Bajie'; per.age = -33; // console.log(per); class A{ protected num: number; constructor(num: number) { this.num = num; } } class B extends A{ test(){ console.log(this.num); } } const b = new B(123); // b.num = 33; /* class C{ name: string; age: number //You can define attributes directly in the constructor constructor(name: string, age: number) { this.name = name; this.age = age; } }*/ class C{ //You can define attributes directly in the constructor constructor(public name: string, public age: number) { } } const c = new C('xxx', 111); console.log(c); })();
3.3 interface
The function of an interface is similar to that of an abstract class. The difference is that all methods and attributes in the interface have no real values. In other words, all methods in the interface are abstract methods. The interface is mainly responsible for defining the structure of a class. The interface can restrict the interface of an object. An object can match the interface only when it contains all the attributes and methods defined in the interface. At the same time, a class can be used to implement an interface. When implementing an interface, all attributes in the interface should be protected in the class.
Example (check object type):
interface Person{ name: string; sayHello():void; } function fn(per: Person){ per.sayHello(); } FN ({name:'Monkey King', sayhello() {console.log (`hello, I am ${this.name}`)}});
Example (Implementation)
interface Person{ name: string; sayHello():void; } class Student implements Person{ constructor(public name: string) { } sayHello() { console. Log ('Hello, I am'+this.name); } }
example:
(function () {
//Describes the type of an object
type myType = {
name: string,
age: number
};
/*
*Interface is used to define a class structure and define which attributes and methods should be included in a class
*Interfaces can also be used as type declarations
* */
interface myInterface {
name: string;
age: number;
}
interface myInterface {
gender: string;
}
// const obj: myInterface = {
// name: 'sss',
// age: 111,
//Gender: 'male'
// };
/*
*Interfaces can restrict the structure of classes when defining classes,
*All attributes in the interface cannot have actual values
*The interface only defines the structure of the object without considering the actual value
*All methods in the interface are abstract methods
*
* */
interface myInter{
name: string;
sayHello():void;
}
/*
*When defining a class, you can make the class implement an interface,
*Implementing an interface is to make the class meet the requirements of the interface
* */
class MyClass implements myInter{
name: string;
constructor(name: string) {
this.name = name;
}
sayHello(){
console. Log ('Hello ~ ~ ');
}
}
})();
3.4 generic
When defining a function or class, in some cases, the specific type to be used cannot be determined (the type of return value, parameter and attribute cannot be determined), and then the generic type can play a role.
for instance:
In this example, the test function has a parameter whose type is uncertain, but the type of its return value is the same as that of the parameter when it can be determined. Because the type is uncertain, any is used for both the parameter and the return value, but it is obviously inappropriate to do so. First, using any will turn off the type check of TS. second, this setting cannot reflect that the parameter and the return value are of the same type
function test(arg: any): any{
return arg;
}
Use generics: <t> here is a generic type. T is the name we give the type (not necessarily T). After setting a generic type, t can be used in the function to represent the type. So generics are actually very easy to understand. They represent a certain type.
function test<T>(arg: T): T{
return arg;
}
So how do I use the above function?
-
Method 1 (direct use):
When using, parameters can be passed directly, and the type will be automatically inferred by ts. however, sometimes the following methods need to be used when the compiler cannot automatically infer
test(10)
-
Method 2 (specify type):
You can also specify generics manually after a function
test<number>(10)
Multiple generics can be specified at the same time, and the generics are separated by commas:
When using generics, you can use generics as a common class
function test<T, K>(a: T, b: K): K{ return b; } test<number, string>(10, "hello");
In addition, you can constrain the scope of generics
Use t extensions myinter to indicate that generic t must be a subclass of myinter. It is not necessary to use interface classes and abstract classes.
interface MyInter{ length: number; } function test<T extends MyInter>(arg: T): number{ return arg.length; }
example:
/*
function fn(a: any): any{
return a;
}*/
/*
*When defining functions or classes, you can use generics if the type is ambiguous
*
* */
function fn<T>(a: T): T{
return a;
}
//Functions with generics can be called directly
let result = fn(10); // Without specifying generics, ts can automatically infer types
let result2 = fn<string>('hello'); // Specify generics
//A generic type can specify more than one
function fn2<T, K>(a: T, b: K):T{
console.log(b);
return a;
}
fn2<number, string>(123, 'hello');
interface Inter{
length: number;
}
//T extensions inter indicates the inter implementation class (subclass) when the generic t must be
function fn3<T extends Inter>(a: T): number{
return a.length;
}
class MyClass<T>{
name: T;
constructor(name: T) {
this.name = name;
}
}
Const MC = new myclass<string> ('Monkey King');
summary
The above are some basic ways to use ts. personally, I think TS is mainly used to limit the types. Starting from the project, you can avoid some bugs. It is more like the background method, which is to write interface to limit the types. Finally, I recommend you a Chinese error prompt for vscode setting. You need to open the setting page, search “typescript local”, and then set the Chinese. If you feel it is OK, please give me a praise, Thank you~