First, the purpose of learning TS
As an open source language developed by Microsoft, TypeScript has been near the top of our favorite languages lists for years. As you might guess from the name, TypeScript is a superset of JavaScript that introduces optional types (among other features) to JavaScript functionality, improving reliability by reducing the chance of errors. Better yet: Angular2It's actually written in TypeScript itself. While there are some technologies that run TypeScript directly -- Deno, Angular -- it is primarily converted to JavaScript and can be used in any Web application.Copy the code
- TypeScript is a strict superset of JavaScript. This means that any and all valid Javascript code works just as well as TypeScript. In fact, “compiling” the typescript actually transpiles code back to vanilla JavaScript. As such, it is compatible with any modern browser and any platform — JavaScript can run almost anywhere — but it provides additional checks at compile time to improve reliability compared to JavaScript.
- Unlike loosely typed JavaScript, TypeScript is strongly typed: you must declare what data each variable will contain. While this can add slightly to the development time of very small, simple programs, many modern software contain thousands of lines of code across multiple files, often written by different authors. In this case, clearly defining what types of variables are acceptable prevents hard-to-locate errors from becoming a reality.
- Beyond that, TypeScript is really just JavaScript, with all the benefits (and some of the drawbacks) of JavaScript.
The basic usage of TS
1. The type of ts
1.1 TS Environment Construction
1.Open the command line and type NPM I -g typescript global install TS2.Go ahead and type tsc-init on the command line for initialization, and you'll find a tsconfig.json file in the root directory that records the options for compiling to JS3.Create ts file4.Open VSCode and enter the directory. Press Ctrl+shift+B to compile5.Enter the node command to run the JS codeCopy the code
npm install -g ts-node
npm install -D tslib @types/node
Copy the code
1.1.1 Running TS in a Browser
- Once the folder is set up, open VSCode, pull the folder into the editor, then open the terminal, run NPM init -y to create package.json file.
- After generating the file, we then run tsc-init in the terminal to generate the tsconfig.json file.
- Create new SRC and build folders, and create an index.html file.
- In the SRC directory, create a new page.ts file. This is the ts file we will write.
- Json file, set outDir and rootDir(around line 15), that is, set the file directory to compile, and the compiled file directory.
- Then write index.html to introduce, while we don’t have a page.js file yet.
- Ts file, console.log(‘jspang.com’), TSC on the console, to generate the page.js file
- Then go to the browser to check the index.html file. If you press F12, you can see jspang.com, which means that our setup is normal.
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<script src='./build/page.js'></script>
<title>Document</title>
</head>
<body>
</body>
</html>
Copy the code
1.2 Basic Type declaration
As a superset of JS, TS supports all data types of JS, including
- Boolean, number, string, null, undefined, Symbol
- Data of the type undefined and NULL can only be assigned to undefined and NULL, but this type is a subtype of all types
- Empty void type
- Any and type inference
1. Undefined and null are subtypes of all types and can be assigned
let num: Symbol = undefined;
let num: number = undefined;
// undefined can only be given as undefined
let u: undefined = undefined;
let n: null = null;
Copy the code
2. In TS, a variable is declared as the default type if its type is not defined
let str;
str = 'I am wangsu';
str = 1024;
// let num= 124;
// let num:number = 124,
If num is given a string, an error will be reported
Copy the code
3. Use of void type
The //void type is like the opposite of any in that it means there is no type. When a function returns no value, you usually see the return type void:
function warnUser() :void {
alert("This is my warning message");
}
// Declaring a void variable doesn't do much good, because you can only give it undefined:
let a: void = undefined;
Copy the code
4. The use of any
Sometimes we want to specify a type for variables whose type is not known at programming time. These values may come from dynamic content, such as user input or third-party code libraries. In this case, we don't want the type checker to check these values and just pass them through compile-time checks. We can then mark these variables with type any:// Any indicates any type, so the following changes will not cause any errors
let ws:any=12
ws="i don't kown my type"
ws="wo shi wagsu"
console.log(ws);
Copy the code
5. Usage of unknown types
Sometimes, the type is unknown in advance, that is, it can be any type. Before TS v3, we used any to define any type. But this deprives TS of its value, such as any type security that TS provides.
/ / use any
const x: any = {
a: "ws".b: "qy"
};
// The attributes of the object, x.a and x.b, can be accessed without any problems.
// the problem is that Typescript doesn't throw an error if you try to access x.c because object x can be anything.
Copy the code
As you can see, this can be a source of many errors, because common errors that Typescript catches during build time will be allowed through. This is because when you use any, you exit type checking. So change the above code to
const x: unknown = {
a: "wx".b: "qy"
};
console.log((x as {a: string; b: string; }).b)
Copy the code
6. Use of the never type
let x: never;
let y: number;
// Error running. The numeric type cannot be converted to never
x = 123;
// The never type can be assigned to the never type
x = (() = >{ throw new Error('exception')}) ();// It works correctly. The never type can be assigned to a numeric type
y = (() = >{ throw new Error('exception')}) ();// A function that returns never can be the case where an exception is thrown
function error(message: string) :never {
throw new Error(message);
}
// A function that returns never can be a terminating point that cannot be executed
const ws=function() :never {
while (true) {}}Copy the code
7. Type derivation
When it is clear that the current type is Number, we can invoke the Number type through type derivation
// If object is lowercase, some methods on the object cannot be called. A type derivation is required for its type
let j:object={}
// If the Object is uppercase, the method on its prototype can be called directly, such as toString().
let j:Object= {}// The j type is the base data type of number
j=new String("123") // the j type is the wrapper type for Number base data
j=new Number(123) // Type derivation converts j to number, which is 0 for a number object, so its toString method can be called
let str=(<Number>j).toString() // The second form of type derivation
let str2=(j as Number).toString(); // The object corresponding to j is lowercase
let str=j.toString()
console.log(str)
Copy the code
8. Assertion
Sometimes you’ll find that you know more about a value than TypeScript does. Usually this happens when you clearly know that an entity has a more exact type than its existing type. Type assertions are a way of telling the compiler, “Trust me, I know what I’m doing.” Type assertion is like conversion in other languages, but without special data checking and deconstruction. It has no run-time impact, only at compile time.
// Angle bracket syntax
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
Copy the code
/ / as syntax
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
Copy the code
1.3 Type Guard
1.3.1 in keyword
interface Admin {
name: string;
peee: string[];
}
interface Emplyee {
name: string;
startData: Date;
}
type UnknownEmployee = Emplyee | Admin;
function printEmplo(emp: UnknownEmployee) {
// Determine that this object contains an attribute
if ("peee" in emp) {
console.log("peee" + emp.peee);
}
if ("startData" in emp) {
console.log("peee"+ emp.startData); }}Copy the code
1.3.2 typeof
Typeof type protection supports only two types: typeof V === “typename” and typeof V! == typename, “typename” must be “number”, “string”, “Boolean” or “symbol”. But TypeScript doesn’t prevent you from comparing with other strings, and the language doesn’t recognize those expressions as type-protected.
let ws:number
let qy:typeof ws=1234
console.log(qy);
Copy the code
1.3.3 instanceof
interface Padder{
// Define a function type whose return value is a string
getPaddingString():string
}
// Define a class
class SpaceReapeat implements Padder{
constructor(private numSpaes:number){}getPaddingString(){
return Array(this.numSpaes+1).join(' ')}}let padder:Padder=new SpaceReapeat(6)
if(padder instanceof SpaceReapeat){
}
Copy the code
1.3.4 is
function isNumber(x: any) :x is number {
return typeof x === "number";
}
function isString(x: any) :x is string {
return typeof x === "string";
Copy the code
1.4 the enumeration
Enumerations can be used to clarify our developers’ intentions with constants whose names make sense
1.4.1 Heterogeneous Enumeration
enum Order{
start='start',
name='ws',
age=12
}
console.log( Order);
//{ '12': 'age', start: 'start', name: 'ws', age: 12 }
Copy the code
1.4.2 Reverse mapping of numeric enumeration
enum Shop{
first=0,
second=1,
end=3
}
console.log(Shop.first);/ / 0
console.log(Shop[Shop.first]);//first
Copy the code
1.5 an array
Arrays are strings, objects, tuples, numbers
// Array defines the first way
let list:number[]=[1.23.5.3.5.76.3]
console.log(list)
// The second way to define arrays is to use Array generics, Array< element type > :
let arr:Array<number>=[1.4.6.87]
console.log(arr)
Copy the code
1.5.1 tuples
Ts arrays can only hold elements of a single data type. Tuples can solve this problem. The tuple type allows you to represent an array with a known number and type of elements that need not be of the same type. For example, you can define a pair of tuples of type string and number.
// There is a one-to-one correspondence between the preceding bracketed data types and the following bracketed data types
let list1:[string,number,null] = ["ws".1234.null]
console.log(list1)
Copy the code
1.5.1.1 Attributes of tuples
- Tuples can be read-only
When assigning a read-only tuple type, it is allowed to assign a regular tuple type to a read-only tuple type, but not to assign a read-only tuple type to a regular tuple type
const ws:readonly[number,number]=[0.0]// Data in a tuple is readable only
Copy the code
- Elements in tuples can be optional, using?
const arr=[t1,t2,t3?,...tn?]
Copy the code
- Remaining elements in a tuple
const ws:[number,strig,...string[]]=[0.'s'.'d'.'f'.'g']
Copy the code
1.6 the function
1.6.1 Type Alias of a function
type age=number;
type AgeCreater=() = >age;
function getAge(arg:AgeCreater) :age{
return arg()
}
Copy the code
1.6.2 Function overloading
Function overloading refers to a group of functions that have the same function name and different parameter lists in the same scope. This group of functions is called overloaded functions. Overloaded functions are usually used to name a group of functions that have similar functions. This reduces the number of function names and avoids namespaces contamination, which is of great benefit to program readability. In simple terms, the function name is the same, the function parameters are different
Function overload declarations can be multiple, but implementations can have one
// Function overloading: the function names are the same, but the function parameters are different
// function declaration
function fn(name:string,age:number) :void;
function fn(name:string,age:number,gender:string) :void;
// Function implementation
function fn(name:string,age:number,gender? :string) :void{
if(arguments.length>2) {console.log("The function takes three arguments.")}else{
console.log("The function takes two arguments.");
}
}
fn("Suziewong".20)
fn("Suziewong".20."Male")
Copy the code
// Function overloading: Overloading means that the method name is the same, but the parameters are different, and the return type can be the same or different.
// Every overloaded method (or constructor) must have a unique list of argument types.
// Different parameter types:
function disp(string) :void;
function disp(number) :void;
// The number of parameters is different:
function disp(n1:number) :void;
function disp(x:number,y:number) :void;
// Different order of parameter types:
function disp(n1:number,s1:string) :void;
function disp(s:string,n:number) :void;
Copy the code
1.6.3 Function Parameter Types
1. Add? To function parameters Indicates that the parameter is optional
/ /? The symbol indicates an optional parameter
function fn2(name? :string,gender? :string) :number{
return 1
}
console.log(fn2("Suziewong"))/ / 1
console.log(fn2("Suziewong"."Male"))/ / 1
Copy the code
2. In function parameters, = indicates the default parameter of the function
function fn3(name:string,gender:string="Male"){
return gender
}
console.log(fn3("Suziewong"))/ / male
Copy the code
3…. Residual argument, residual argument usually refers to the last argument of the function
function fn4(name:string,... arg:string[]) :number{
console.log(arg)
return 1;
}
fn4("Zhang"."Bill"."Sun Xiao"."Household Philippines")//[' Li Si ', 'Sun Xiao ',' Hu Fei ']
Copy the code
4. The function has no return value
function sayHello() :void {
console.log("hello world");
}
Copy the code
1.7 object
1.7.1 Interface Keyword
interface s{
a:number,
b:string,
c:number[]
}
let v:s={
a:1.b:'qy'.c: [1.2.3.4]}console.log(v);
Copy the code
1.7.2 Optional Properties
interface Person {
name: string; age? : number; }let tom: Person = {
name: 'Tom'
};
Copy the code
1.7.3 Arbitrary Attributes
interface Person {
name: string; age? : number; [propName: string]: any; }let tom: Person = {
name: 'Tom'.gender: 'male'
};
Copy the code
1.7.4 Read-only Properties
interface Person { readonly id: number; name: string; age? : number; [propName: string]: any; }let tom: Person = {
id: 89757.name: 'Tom'.gender: 'male'
};
tom.id = 9527;
Copy the code
2. Calss class in TS
2.1 Basic Usage
/ / that class
class Person {
// Attributes, member variables
name: string = "Zhang";
age: number;
// Constructor, the method that creates the object by default
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// Define methods, member methods
// Member variables, member methods can only be called by the current object, the current class cannot call directly
sayHello(msg: string="Default information") :void {
console.log(this.name + msg); }}let p1=new Person("Suziewong".20)
p1.sayHello()
Copy the code
2.2. Inheritance
2.2.1. Extends
/ / that class
class Person {
// Attributes, member variables
name: string = "Zhang";
age: number;
// Constructor, the method that creates the object by default
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// Define methods, member methods
// Member variables, member methods can only be called by the current object, the current class cannot call directly
sayHello(msg: string="Default information") :void {
console.log(this.name + msg); }}// Student inherits the methods and attributes of the current Person class
class Student extends Person{}let p2=new Student("Suziewong".23)
p2.sayHello()
Copy the code
2.2.2 super
/ / that class
class Person {
// Attributes, member variables
name: string = "qy";
age: number;
// Constructor, the method that creates the object by default
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// Define methods, member methods
// Member variables, member methods can only be called by the current object, the current class cannot call directly
sayHello(msg: string="Default information") :void {
console.log(this.name + msg); }}// Student inherits the methods and attributes of the current Person class
class Student extends Person{
// Here is the student's own property
gender:string;
constructor(name:string,age:number,gender:string){
// Call the parent constructor to initialize the name and age information
// Super must be in the first place
super(name,age)
// Initialize your gender information
this.gender=gender;
}
sayHello(msg: string="Default information") :void {
// Use super to call the method of the parent class
super.sayHello();
// Prints information about the current subclass
console.log("Current gender :".this.gender)
}
}
let p2=new Student("Suziewong".23."Male")
p2.sayHello()
Copy the code
2.3. Member variables
2.3.1. Public
A common member variable, which is the default and can be inherited by subclasses
/ / that class
class Person {
// Attributes, member variables, here are common member variables
public name: string = "Zhang";
public age: number;
// Constructor, the method that creates the object by default
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// Define methods, member methods
// Member variables, member methods can only be called by the current object, the current class cannot call directly
sayHello(msg: string="Default information") :void {
console.log(this.name + msg); }}// Student inherits the methods and attributes of the current Person class
class Student extends Person{
// Here is the student's own property
gender:string;
constructor(name:string,age:number,gender:string){
// Call the parent constructor to initialize the name and age information
// Super must be in the first place
super(name,age)
// Initialize your gender information
this.gender=gender;
}
sayHello(msg: string="Default information") :void {
// Use super to call the method of the parent class
super.sayHello();
// Prints information about the current subclass
console.log("Current gender :".this.gender)
}
}
let p1=new Person("Suziewong".20)
p1.sayHello()
let p2=new Student("qy".23."Female")
p2.sayHello()
Copy the code
2.3.2 private
A private member variable that is unique to the parent, cannot be inherited and can only be used within the current class
/ / that class
class Person {
// Attributes, member variables
public name: string = "Zhang";
public age: number;
private job:string="IT"
// Constructor, the method that creates the object by default
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// Define methods, member methods
// Member variables, member methods can only be called by the current object, the current class cannot call directly
sayHello(msg: string="Default information") :void {
console.log(this.name + msg);
// Only private member variables can be used in the current class
console.log(this.job)
}
}
// Student inherits the methods and attributes of the current Person class
class Student extends Person{
// Here is the student's own property
gender:string;
constructor(name:string,age:number,gender:string){
// Call the parent constructor to initialize the name and age information
// Super must be in the first place
super(name,age)
// Initialize your gender information
this.gender=gender;
}
sayHello(msg: string="Default information") :void {
// Use super to call the method of the parent class
super.sayHello();
// Prints information about the current subclass
console.log("Current gender :".this.gender)
}
}
let p1=new Person("Suziewong".20)
p1.sayHello()
let p2=new Student("Suziewong".23."Male")
p2.sayHello()
Copy the code
2.3.3. Protected
A protected member variable can only be used in the current class and its subclasses and cannot be accessed externally
//protected- Similar to private but can be inheritedclass Person {
protected name: string;
constructor(name: string) {
this.name = name; }}class Employee extends Person {
private department: string;
constructor(name: string, department: string) {
super(name)
this.department = department;
}
public getElevatorPitch() {
return `Hello, my name is The ${this.name} and I work in The ${this.department}. `; }}let howard = new Employee("Howard"."Sales");
console.log(howard.getElevatorPitch());
console.log(howard.name); / / error
// Note that we cannot use name outside of the Person class, but we can still pass
// Access the instance method of the Employee class, since Employee is derived from Person.
Copy the code
2.4 the Setter and Getter
Access and modify private properties in the form of getters and setters.
/ / that class
class Person {
// Attributes, member variables
public name: string = "Qin Ying";
public age: number;
// Private member
private _job: string = "IT";
// Protected member variables
protected house: string = "This is a nice house.";
// Constructor, the method that creates the object by default
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// Access private members indirectly from outside
set job(job: string) {
console.log("Current set method executed")
this._job = job;
}
get job() :string {
return this._job;
}
// Define methods, member methods
// Member variables, member methods can only be called by the current object, the current class cannot call directly
sayHello(msg: string = "Default information") :void {
console.log(this.name + msg);
// Only private member variables can be used in the current class
console.log(this._job); }}// Student inherits the methods and attributes of the current Person class
class Student extends Person {
// Here is the student's own property
gender: string;
constructor(name: string, age: number, gender: string) {
// Call the parent constructor to initialize the name and age information
// Super must be in the first place
super(name, age);
// Initialize your gender information
this.gender = gender;
}
sayHello(msg: string = "Default information") :void {
// Use super to call the method of the parent class
super.sayHello();
// Prints information about the current subclass. Private member variables are now accessible because of get
console.log("Current gender :".this.gender,this.job); }}let p1 = new Person("Suziewong".20);
p1.sayHello();
let p2 = new Student("Suziewong".23."Male");
p2.sayHello();
let stu=new Student("Xiao Ming".21."Male")
// The job is passed as an argument to the set method
stu.job="teacher"
stu.sayHello()
Copy the code
2.5 Static Members
Members that do not require instantiation access are called static members, that is, members that can only be accessed by the class
The static keyword
class Person {
// Static variables
static country = "china";
// The kyota method
static sayhello() {
console.log("hello")}constructor () {}}let p1 = new Person();
let p2 = new Person();
console.log(Person.country) // Static variable, accessed directly by type
console.log(p1.country) / / error
Copy the code
2.6 the abstract class
Pass a method by encapsulating an abstract class, but the functionality of the method is varied
abstract class Girl{
abstract skill() // There is no specific method, so we do not write parentheses here
}
class Waiter extends Girl{
skill(){
console.log('Ws, please drink water! ')}}class BaseTeacher extends Girl{
skill(){
console.log('Ws, have a Thai massage! ')}}class seniorTeacher extends Girl{
skill(){
console.log('Ws, let's have a full body SPA massage! ')}}Copy the code
3. The interface
3.1 Interfaces Standardize classes
Declare an interface for Human, which describes the attributes that Human should have. The line interface can be used for class specification, but also can be used for object specification
interface Human{
name:string;
age:number;
gender:string;
say():void;
}
// Implement the interface
class People implements Human{
name:string="Suziewong";
age:number=20;
gender:string="Male";
say():void{
console.log("Implementation interface")}; }// Interfaces can be implemented by many classes
class Enginer implements Human{
name:string="Qin Ying";
age:number=20;
gender:string="Female";
say():void{
console.log("Implement interface conversion")}; }Copy the code
3.2 Interface Specifications for objects
interface Shape {
head: string;
arm: string;
}
interface Person {
name: string;
age: number;
shape: Shape;
say(word: string): void;
}
let jack: Person = {
name: 'Jack'.age: 18.shape: {
head: 'head'.arm: 'arm'
},
say(word: string) {
console.log(word)
}
}
jack.say('hi')
Copy the code
3.3 Interface Attributes
- The read-only property of the interface
Some object properties can only change their value when the object is created. You can specify read-only properties with readonly before the property name:
interface Person {
readonly name: string
}
let jack: Person = {
name: 'ws'
}
jack.name = 'qy' // error: Name is read-only
Copy the code
- Optional properties of the interface
Not all attributes in the interface are required. Some exist only under certain conditions, or not at all. Optional properties are commonly used in the “Option Bags” mode, where only part of the parameter object passed to the function is assigned a value.
interface Person {
gender: string, age? : number }let jack: Person = {
gender: 'qy'
// The age attribute can be left unassigned because it is optional
}
Copy the code
4. The generic
4.1 Generic constraints
A generic type cannot know the specific type, so it cannot manipulate its properties and methods
function Test<T> (a:T) :void {
console.log(a.length); // error
}
Test<string>('ws')
Copy the code
When you know exactly what attribute methods are in a generic, you can apply the generic constraint through extends, which comes after the declared function name
interface hasLengthProp {
length : number;
}
function Test<T extends hasLengthProp> (a:T) :void {
console.log(a.length);
}
Copy the code
Using generics to constrain generics, inheritance is used
function change<T extends U.U> (a:T,b:U) :void {
console.log(a);
}
change({a:1.b:2.c:3}, {a:1.b:2})
Copy the code
4.2. Generic interfaces
Define generics in the interface. If only one anonymous function type is defined in the interface, assign it directly
interface Test {
<T>(name:T):void
}
let say:Test; // Assign directly
say = function<T> (name:T) :void {
console.log(name);
}
say('ws')
Copy the code
If the interface contains more than one property, the interface is a description of an object
interface objType {
demo<T>(name:T):void;
age:string;
}
let say:objType; // Object description
say.demo = function<T> (name:T) :void {
console.log(name);
}
say.demo<string>('ws')
Copy the code
4.3. A generic class
The section on using type variable classes in generics says that classes have two parts: a static part and an instance part. A generic class refers to the type of the instance part, so static attributes of the class cannot use this generic type
class SelectGirl<T> {
constructor(private girls: T[]) {}
getGirl(index: number): T {
return this.girls[index]; }}const selectGirl = new SelectGirl(["ws"."ee"."qy"]);
console.log(selectGirl.getGirl(1));
Copy the code
4.4 Generic defaults
The default takes effect when there is no direct specification in the code and type inference does not succeed
function say<T = any> (name: T) :void {
console.log(name)
}
say<string>('ws') // ok
say(true) // ok
Copy the code
5. Namespace namespace
The syntax of namespace is similar to the idea of modularity in programming. For example, when webpack is packaged, each module has its own environment and does not pollute other modules. No global variables are generated. A namespace is very similar to this, but notice that it’s similar, not identical.
5.1. Same file implementation interface
namespace API{
export let obj={
name:"Ha ha"}; }console.log(API.obj)
Copy the code
5.2 Multiple file implementation interface
You can export only interfaces or classes, not values. If values need to be exported, you also need to export the namespace
- 1. Export defined interfaces in A. ts
namespace API{
export interface Ishape{
draw():void}}Copy the code
- 2. This interface can be implemented in B.ts
draw:function(){
console.log("draw")
}
}
aa.draw();
Copy the code
5.3 Directly Exporting Values
- In a.ts, you need to export not only interfaces and objects, but also namespace
export namespace API{
export let obj={
name:"Ha ha"};export interface Ishape{
draw():void}}console.log(API.obj)
Copy the code
- Implement interface in B. ts and import namespace exported in A. ts
// The path must be relative
import {API} from "./a"
let aa:API.Ishape={
draw:function(){
console.log("draw")
}
}
aa.draw();
console.log(API.obj)
Copy the code
takeaway
This document summarizes the basic usage of TS, there are advanced usage has not been summarized, because the work uses TS a lot, so I take the time to sort out TS, review part of the grammar of TS, just for reference, I eat a piece of the document is boring, have nothing to do at workCopy the code