第一章:Typescript概述

1.TS介绍

1.Typescript是以JavaScript为基础构建的语言,Typescript扩展了JavaScript并添加了类型,可以在任何支持JavaScript的平台中执行,TS不能被js解析器直接执行,因此要把ts转换为js代码来执行
2.ts增加了类型,面向对象的

ts开发环境搭建:下载node.js  安装node.js 进入命令行 输入 npm i-g typescript  创建一个ts文件 使用tsc对ts进行编译



2.基本类型:类型声明

let a:number;//这个声明了一个变量a,同时指定他的类型为number
//因为a的类型设置为了number 在以后的使用过程a的值只能是数字
a=10;
// a='hello';//这个就是报错,因为类型不匹配
console.log(a);

let b:String;
b='计算机科学与技术';
console.log(b);
//如果变量的声明和赋值是同时进行的,ts可以自动对变量进行类型检测





function sum(x :number,y:number) {
    return x+y;
}

function sum1(x :number,y:number):number {//声明了函数返回值类型
    return x+y;
}

console.log(sum(1, 23));




//使用字面量来进行类型声明
let a:10;
a=10;

//也可以使用 | 或来连接多个字符、
let b: boolean|string;//这个语句读作b的类型可以是布尔值也可以是字符串
b=true;
b='计算机科学与技术';


//any 任何类型,任意赋值,一个类型设置为any后相当于对变量关闭了ts的类型检测  不建议使用
let  d:any;
//也就是d变量可以随意赋任意类型的值
d=true;
d='计算机科学与技术';
d=2;

//声明变量如果不指定类型,则ts解析器会自动判断变量的类型为any



//unknown 表示未知类型的值  这个就是一个类型安全的any
let e:unknown;
e=10;
e='计算机科学与技术';
e=true;

//类型断言 可以用来告诉解析器变量的实际类型
let s;
s=e as string;


//void
function fn() :void{//返回值为空值
    return null;
}

//never表示永远不会返回结果
// @ts-ignore
function fn2() :never{
    
}

2.环境搭建

1.下载node

2.安装node

#3.进入 终端  输入 npm i -g typescript
		--npx tsc -v查看版本号  检测安装是否成功
4.创建一个ts文件
5.使用tsc 对文件进行编译
		终端在当前文件打开输入:----node 文件名

3.TS中的类型声明

let    a;
a=10;

// a="hello"  这个代码会报错  原因就类型不匹配

console.log(a)

let b:string;//把b的类型变为字符串
b="计算机科学与技术学院"

console.log(b);


//声明变量追进行赋值
let c: boolean=false;
console.log(c);

//如果变量的声明和赋值是同时进行的  ts可以自动对变量进行类型检测

//js中的函数是不考虑参数的类型和个数的
function fn(a,b){

    return a+b;

}

console.log(fn(12, 34));


function sum(a:number,b:number){

    return a+b;
}

console.log(sum(123, 223));


//还可以指定 函数的返回值
function f(a:number,b:number):number {//指定函数的返回值为number

    return a+b;

}

console.log(f(123, 456));

3.TS的类型声明-1

let a:string

//直接使用字面量进行类型声明
let b:10;
b=10;//这个不报错
// b=11  这个就是报错  原因就是已经定义过了



//可以使用|来连接两个数类型
let c:"male" | "female";
c="male"
c="female"


let d:boolean|string//这个就是限制d的类型是布尔或者字符


//any 表表示任意类型  一个变量设置类型为any相对于对该变量关闭了ts的类型检测
let y:any
//在使用ts时  不建议使用any类
y='哈哈哈'
//声明变量如果不指定类型 则ts解析器会自动判断变量类型为any (隐式的any)



//未定义类型
let e:unknown;
e=10



//unknown时候收纳盒就是一个类型安全的any
//unknown类型的变量 不能追赋值给其他变量


//类型断言  高速编译器 e就是字符串  直接强行赋值
d=e as string
d=<string>e//两种写法完全等价




/*
* void用来表示  以函数为例  就表示没有返回值的函数
*
* */
function fn1():void{//这个就是设置了函数的返回值为空  没有返回值


}


//never  表示永远不会有结果
function fu2():never{

    throw new Error("报错了??")//有这种情况用never就可以

}

4.TS的类型声明-2

//object 表示一个对象
let a:object;
a={};
a=function fn() {
    console.log("对象")
}


//{}用来指定对象中可以包含那些属性
let b:{name:string};//这个对象可以指定属性
b={name:'吴邪'}
console.log(b);
//在属性后面加上 一个? 代表属性是可选的
let c:{name:string,age?:number,[proName:string]:any}
//[proName:string] any 表示任意类型的属性



/*
* 设置函数结构的类型声明:
*       语法:(形参:类型,形参:类型...)=>返回值
*
* */
let d:(a:number,b:number)=>number
d=function g(n1,n2){
    return n1+n2
}
console.log(d(12,67))


//string[] 表示字符串类型
let e:string[]
e=['a','b','c']


//number[]  表示数值数值
let f:number[];
let g:Array<number>;

/*
* 数组的类型声明:
*       --类型[]
*
* 元组:就是固定长度的数组
*       语法:[类型,类型 ,类型]
* */
let h:[string,string];
h=['hello','计算机'
]
console.log(h);

/*
* 枚举
*       enum
* */

let i:{name:string,gender:string};
i={

    name:'孙悟空',
    gender:'男'
}

console.log(i.name)

//定义枚举:
enum Gender{
    Male,
    Femle,
}
let j:{name:string,gender:Gender};
j={
    name:'吴邪',
    gender:Gender.Femle

}

console.log(j.gender===Gender.Femle)


//&表示且 这样子是没有意义的
let k:{name:string}&{number:number};


//类型的别名
type myType=string
let o:1|2|3|4|5
let l:1|2|3|4|5
let m:myType//起名来代替

5.TS编译选项-1

console.log("hello")

//在终端编译ts的时候  可以这样子 tsc  文件.ts -w  就可以自动编译

let a=10
var c="计算机科学"
console.log(c);

let obj:{
    name:'吴邪',
    age:19

}
console.log(obj.age)


//终端输入  tsc  直接就可以把全部ts文件编译  但是要完成这个操作 需要建立一个ts的配置文件
{

/*
tsconfig.js是ts编译器的配置文件 ts编译器可以根据它的信息来对代码进行编译

        --  "include": []用来绝对那些ts文件需要编译 /**表示任意目录
                * 表示任意文件

*/


    "include": [
        "./src/**/*"
    ],

//    这个是可选的
    "exclude": [
        "./src/hello/**/*"//表示被排除的文件 不需要被编译的文件目录
    ],

    "extends": ""//表示继承那个文件
}

6.TS编译选项-2

{
/*
tsconfig.js是ts编译器的配置文件 ts编译器可以根据它的信息来对代码进行编译
        --  "include": []用来绝对那些ts文件需要编译 /**表示任意目录
                * 表示任意文件
*/
    "include": [
        "./src/**/*"
    ],
    /*
    "compilerOptions": {} 编译器的选项
    */
"compilerOptions": {
    "target": "ES2020",//用来指定ts被编译为es的版本
    "module": "ES2020",//module指定使用的模块化规范
    "lib": ["dom"],//指定需要使用的库  一般不需要去设置
    "outDir": "",//用来指定编译后文件所在目录  前提是要文件目录存在

//    文件输出目录

    "outFile": "",//将代码合并为一个文件 设置outFile后 所有的全局作用域中的代码会合并到同一个文件中

    "allowJs": false,//是否对js文件进行编译  默认不编译


    "checkJs": false,//是否检查的js是否符合语法规范

    "removeComments": false,//是否移除注释 true 是    FALSE 否

    "noEmit": false,//不生成编译后文件
    
    "noEmitOnError": false,//当有错误时 不生成编译后的文件
}
}

7.TS编译选项-3

{
/*
tsconfig.js是ts编译器的配置文件 ts编译器可以根据它的信息来对代码进行编译
        --  "include": []用来绝对那些ts文件需要编译 /**表示任意目录
                * 表示任意文件
*/
    "include": [
        "./src/**/*"
    ],
    /*
    "compilerOptions": {} 编译器的选项
    */
"compilerOptions": {
    "target": "ES2020",//用来指定ts被编译为es的版本
    "module": "ES2020",//module指定使用的模块化规范
    "lib": ["dom"],//指定需要使用的库  一般不需要去设置
    "outDir": "",//用来指定编译后文件所在目录  前提是要文件目录存在

//    文件输出目录

    "outFile": "",//将代码合并为一个文件 设置outFile后 所有的全局作用域中的代码会合并到同一个文件中

    "allowJs": false,//是否对js文件进行编译  默认不编译


    "checkJs": false,//是否检查的js是否符合语法规范

    "removeComments": false,//是否移除注释 true 是    FALSE 否

    "noEmit": false,//不生成编译后文件
    
    "noEmitOnError": false,//当有错误时 不生成编译后的文件

    "alwaysStrict": false,//用来设置编译后文件是否使用严格模式 默认为false


    "noImplicitAny": false,//不允许隐式的Any类型


    "noImplicitThis": false,//检查隐式的this

    "strictNullChecks": false,//非空检测

    "strict": false,//严格检查的总开关  只要一设置true所有检查都会打开
}
}

8.使用Webpack打包代码

1.终端输入:npm init -y
		在输入:npm i -D		安装开发依赖
		在输入:npm i -D webpack webpack-cli typescript ts-loader  安装好依赖之后
		
		
	
//1.先引入一个包
const path=require('path')

module.exports={

//    在webpack中的配置信息都应该写在这里


//  指定入口文件
    entry: "./src/index.ts",


//    指定打包文件位置

output:{

//        指定打包后的文件目录
    path:path.resolve(__dirname,'dist'),

//    指定打包后文件名字
    filename:"bundle.js"

},


//    指定Webpack打包时 使用的模块
    module:{

    //    指定要加载的规则
        rules:[
            {
                //这个指定是规则生效的文件
                test:/\.ts$/,
                //要使用的loader
                use:'ts-loader',

            //    要排除的文件夹
                exclude:/node-modules/


            }

        ]

    }

}
{
  "name": "pro-3",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",

  "build":"webpack"//书写这个 构建代码
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "ts-loader": "^9.4.2",
    "typescript": "^4.9.4",
    "webpack": "^5.75.0",
    "webpack-cli": "^5.0.1"
  }
}
{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "sourceMap": true
  },
  "exclude": [
    "node_modules"
  ]
}
终端输入npm run build运行

9.Webpack打包代码-2

安装Webpack插件:
终端输入:npm i -D html-webpack-plugin

	
//1.先引入一个包
const path=require('path')


//2.引入html-Webpack插件
const HTMLWebpackPlugin=require('html-webpack-plugin')

module.exports={

//    在webpack中的配置信息都应该写在这里


//  指定入口文件
    entry: "./src/index.ts",


//    指定打包文件位置

output:{

//        指定打包后的文件目录
    path:path.resolve(__dirname,'dist'),

//    指定打包后文件名字
    filename:"bundle.js"

},


//    指定Webpack打包时 使用的模块
    module:{

    //    指定要加载的规则
        rules:[
            {
                //这个指定是规则生效的文件
                test:/\.ts$/,
                //要使用的loader
                use:'ts-loader',

            //    要排除的文件夹
                exclude:/node-modules/


            }

        ],
    },

    plugin: [
        //配置完毕后  自动生成html文件
        new HTMLWebpackPlugin(),

    ]

}



插件: npm i -D clean-webpack-plugin  可以做到实时更新最新文件

10.Webpack打包代码-3

终端输入:
	npm i -D @babel/core @babel/preset-env babel-loader core-js

第二章:面向对象

1.面向对象介绍

//1.使用class关键字定义一个类



/*              对象中主要包含两个部分:
*                               属性
*                               方法
*
*
*
* */
class Person{
    name:string ='吴邪';
    gender:string='男';
    age:number=19

    static sys :string='安卓系统'
    
    readonly address:string='吴山居';//以readonly开头的属性是只读属性 不能修改
}


const per=new Person();
console.log(per.name,per.age)



/*          对定义的属性是实例属性 需要通过对象的实例去访问
                const per=new Person()
                    per.name
               使用static开头的属性是静态属性(类属性)  可以直接通过类对象去访问   
* 
* */

//:类属性 或者静态属性
console.log(Person.sys)

per.name='王胖子';


/*
* 定义方法:
*           如果在方法前面使用static关键字开头就是静态方法  可以通过类名直接调用
* */
class hero{
    
    test(){

        console.log("你好!")
        
    }
}

2.构造函数和this

class Person{
        name='吴邪';
        age=90
    
    bark(){

            alert("你好  计算机科学与技术学院")
    }

}


const t=new Person();
console.log(t.name);
//对象:t
console.log(t);


class Person2{

    name:string;
    age:number;

//    构造函数会在对象创建的时候调用
    constructor(name:string,age:number) {
        //在实例方法中  this就表示当前的实例  在构造函数中当前对象就是当前新建的那个对象
        //在构造函数可以通过this向新建对象中添加属性


            this.name=name;
            this.age=age;


    }

    bark(){
        //在方法中可以通过this来表示当前调用方法的对象
        console.log(this.name)

    }
}

const  x=new Person2("吴邪",45);
console.log(x);

console.log(x.bark());

3.继承简介

//定义一个类
class Dog{

    name:string;
    age:number
    constructor(name:string,age:number) {

        this.name=name;
        this.age=age;
    }


    sayHello(){

        console.log("旺财!")

    }

}

const dog=new Dog("旺财",19);
dog.sayHello()
console.log(dog);


//定义一只猫咪
class Cat{

    name:string;
    age:number;
    constructor(name:string,age:number) {

        this.name=name;
        this.age=age;
    }

    sayHello(){

        console.log("喵喵")
    }

}


const cat=new Cat("咪咪",90)
cat.sayHello()
console.log(cat);


//定义一个Animal类  为父类
class Animal{

    name:string;age:number;
    constructor(name:string,age:number) {

        this.name=name;
        this.age=age;
    }


    //动物的行为定义为参数
    sayHello(behavior:string){
        console.log(behavior)
    }
}

//定义一个子类
class Cat2 extends Animal{

//    使Cat2类继承Animal类
//    在这种情况下 Cat2继承了Animal的所有属性和方法
//    这样只需要写一次  这样子就可以使各个子类同时拥有父类中的所有方法和属性
//    如果希望在子类中添加一些父类中没有的属性和方法

    run(){
        console.log("跑起来了")

    }

}

let cat2 = new Cat2("小猫",12);
cat2.sayHello('喵喵')
cat2.run()


class Dog2 extends Cat2{

//    可以反复套娃  无限下去


//    z注意:如果在子类中添加了和父类相同的方法  则子类方法会覆盖掉父类的方法  这种形式称为方法的重写
    sayHello(behavior: string) {
        super.sayHello(behavior);
        console.log("旺旺")
    }
}

4.super关键字

class Animal{
    name:string;
    constructor(name:string) {

        this.name=name
    };

    sayHello(){

        console.log("大家好!")

    }


}



//继承这个类
class Dog extends Animal{

    sayHello() {
        super.sayHello();//表示父类  在类的方法中  super就表示当前类的父类
    }
}

let dog = new Dog("吴邪");
dog.sayHello();
console.log(dog);


class DogTest extends Animal{
//    如果在子类写了构造函数 在子类构造函数中必须得调用一些父类的构造函数
    age:number;
    constructor(name:string,age:number) {
        super(name);//调用父类的构造函数
        this.age=age;
    }


}

5.抽象类

/*
*       以abstract开头的类为抽象类
*               抽象类和其他类区别不大  只是不能用来创建对象
                抽象类就是用来专门被继承的类*
*
*               当我们不希望用这个类来创建对象的时候  可以使用这个关键字来创建类
*
*               注意:在抽象类中可以添加抽象方法
*
*  */

abstract class Animal {

    name: string;

    sayHello() {
        console.log("你好!")

    };

    //    定义抽象方法  abstract +方法名(){}
//    抽象方法只能定义在抽象类中   注意抽象方法没有方法体  子类必须对抽象方法进行重写
    abstract MyDay():void;
}
//这个类只可以继承  不可以实例化
class Cat extends Animal{

    MyDay() {

    //    重写了这个方法 就不会报错了

        console.log("你好")
    }

}

console.log(Cat);
let cat = new Cat();
console.log(cat.MyDay());

6.接口

//想去描述对象的类型
type myType={

    name:string,
    age:number
}

const obj:myType={

    name:'吴邪',
    age:11
}


//因此我们使用接口:
/*
*           接口:接口就是用来定义一个类结构  用来定义一个类中应该包含那些属性和方法
*       同时接口也可以当成类型声明去使用
*
*
*
* */

interface MyInterface{

    name:string,
    age:number

}

interface MyInterface{
    gender:'男'
}

//使用接口
const x:MyInterface={

    name:'吴邪',
    age:19,
    gender:'男'
}

/*接口可以在定义类的时候去限制类的结构:
*           接口中的所有属性都不能有实际的值  接口只定义对象的结构 而不能考虑实际值  在接口中所有的方法都是抽象方法
*
* */

//定义类时  可以使类去实现一个接口  实现接口就是使类去满足接口的要求
class MyClass implements MyInterface{

    name:'王胖子'
    age:19
    gender:'男'

}

7.属性的封装

第19节课