TypeScript

发布时间:2024年01月20日

一、什么是TS

TS是对js语言的一种规范,如果没有TS,首先js语法过于自由,这就导致往往出错之后,难以排错,从而出现,维护成本高于重构成本。它是对js的一种扩展,最终还是要编译成js代码,再在浏览器中解释运行。

  • 如何安装?
  1. 首先安装node.js.
  2. 然后利用node.js中的npm(包管理器)输入如下指令下载ts
npm install -g typescript

二、类型规范与声明

(一)所有类型和相关细节:

  • 如何声明类型及相关细节:
//1.声明a为string类型
let a:string;
//a = 23;//报错
a = "我爱你";
//2.直接声明类型后赋值或者直接赋值,都能起到限制类型的作用
let b: 3|4|"我爱你" = 4;
//let c: 3|4|"我爱你" = 1;//报错,因为没有在字面量限制中,故无法成功。
//3.函数中类型的声明
function me(a:number,b:string):number{
     return a;
     //参数中规定参数的类型,后面number规定返回值类型。
};
//3.1在声明函数前,规定函数的参数类型和返回值
let meTwo: (a:number,b:string,[args]:any)=>number;
meTwo = function(a,b,r){
    return a;
    //[args]:any,意为不限制传入参数个数,随意。
}
//4.对象中属性类型的限制
//因为在js中函数和对象是混为一谈的,所以在ts中对象应该如下声明:
let e:{ name: string, age:number};
 e = {
    name:"托尼",
    age: 18
//上面方式无法再声明其他属性
}
//4.1如何仅限定必要属性,而不影响未规定属性的添加?
let f: {name:string,age:number,[xx:string]:any}
//意为规定必须有name和age属性,但是其他属性名只要是string类型,值可以是随意,即实现了我们预想的效果。
f = {
    name: "华为",
    age: 23,
    lover: "小米"
}
//5.枚举类型
enum g{
    mele=0,
    female=1
}
let h: {name: string,gender:g}
h={
    name: "托尼",
    gender:g.female,
}
//6.类型的别名常用于自定义字面量类型
type myType = 1|3|"我爱你";
let i: myType;

三、配置文件内容

(一)常用的配置文件内容注释:

{
  "include":["../MYTS/**/*"],//指定要编译的文件路径 **表示任意文件夹 * 表示任意文件
  "exclude": [],//一般不用,会有默认值将一些不需要编译的包排除在外。
  //"files": [],//指定要被编译的文件列表
  "compilerOptions": {
    //指定编译后的js文件所在的目录
    "outDir": "../compilerOptions",
    //outFile,将编译后的代码合并到一个文件输出,注意这里不支持使用es6模块化的ts文件进行合并
    //"outFile": "",
    //是否对js文件进行编译,默认是false
    "allowJs": true,
    //是否检查js代码是否符合语法规范,默认是false
    "checkJs": false,
    //是否移除注释
    "removeComments": false,
    //当有错误时不生成编译后的文件
    "noEmitOnError": false,
    //alwaysStrict,用来确定编译完毕的js代码是否使用严格模式,
    "alwaysStrict": true,//注意如果使用模块化,将自动使用严格模式。
    //不允许隐式的any类型
    "noImplicitAny": true,
    //不允许没有明确指向的this
    "noImplicitThis": false,
    //严格检查空值
    "strictNullChecks": false,
    //所有严格检查的总开关
    // "strict": false
  }
}

(二)一些配置的解释

A、this指向不明确

function myFunction(){
    console.log(this);
}//不知道何人调用,就是指向不明确

B、可能空值

let button = document.getElementById("box1");
button.addEventListener("click",()=>{
    alert("one");
})
//存在box1这个元素不存在的隐患

解决:

let button = document.getElementById("box1");
//1.加上判断
if(button != null){
button.addEventListener("click",()=>{
    alert("one");
})}
//2.使用修饰符
button?.addEventListener("click",()=>{
    alert("one");
})

四、webpack打包

(一)使用webpack

A、执行包管理工具npm,产生文件结构

npm init -y

后产生文件package.json

B、首先下载需要的包

npm install -D webpack webpack-cli typescript ts-loader

下载完毕后,就会在文件夹中多出两个,一个文件夹node_modules,一个文件package-lock.json

C、创建webpack.config.js(webpack的配置文件)

let path = require("path");
module.exports = {
    //指定入口文件
    entry: "./src/myFirstTest.ts",
    //指定打包文件所在目录
    output:{
        //指定打包文件的目录
        path: path.resolve(__dirname,'dist'),
        //打包后文件的文件
        filename: "bundle.js"
    },
    mode: "production",
    //指定webpack打包时要使用的模块
    module:{
        ///指定要加载的规则
        rules:[
            {
                //test指定的是规则生效的文件
                test: /\.ts$/,
                //要使用的loader
                use: 'ts-loader',
                //要排除的文件
                exclude: /node_modules/ ,
            }
        ]
    }
}

D、调整文件位置

最后根据配置文件中的入口地址等信息,将对应文件放在对应位置,同时ts配置文件也要声明正确的路径,这里我是把入口文件放在了src文件夹中了。

这里的dist文件夹还未生成!

E、最后执行命令生成打包后的文件bundle.js

npm  run build

(二)webpack插件使用

A、html-webpack-plugin

  • 下载html-webpack-plugin插件
npm install html-webpack-plugin
  • 在webpack.config.js中引入并使用
let HtmlWebpackPlugin = require("html-webpack-plugin");
//下面省略的其他配置
module.exports = {
 //使用插件
   plugins:[
    new HtmlWebpackPlugin({
        title:"我的第一个页面",//自定义选项,可选
        template: ""//指定自定义html模版的路径,那么生成的html文件就会跟指定的html文件一致。    
    }),
]
}
  • 最后再次运行即可发现我们要使用的js文件都被引入了一个新创建的index.html文件中。

B、webpack-dev-server

  • 安装webpack-dev-server
npm install -D webpack-dev-server
  • 修改配置,在package.json中的scripts选项中增加如下配置:
"start": "webpack serve --open --mode production"
  • 最后运行npm run start即可发现页面自动被打开到默认浏览器中,并且会进行实时更新。

C、clean-webpack-plugin

  • 安装clean-webpack-plugin
npm install -d clean-webpack-plugin
  • 配置
//引入clean-webpack-plugin
let {CleanWebpackPlugin}  = require("clean-webpack-plugin");
module.exports = {
 //使用插件
   plugins:[
    new CleanWebpackPlugin,

]
}
  • 如此每次结构发生变化,再进行打包的时候,就可以自动删除之前打包内容,而不是同名才进行覆盖。

(三)一些配置

A、resolve

默认webpack不知道ts也可进行模块化引入,所以要在webpack.config.js加入配置

resolve:{
        extensions:[".ts",".js"],//指定后缀为js或者ts的都可以作为模块
    }

五、对象、类、抽象类、接口、属性封装、泛型

总述:总的来看,js现在在新的es标准中增加了类,ts在js增加的类的基础上又增加了其他几种,更加完善和完备。这里学过java的对这些概念的理解会比较快!

A、类和对象

类和对象的关系就像动物和狗、猫等的关系,对象的抽象叫做类,类的具体实现叫做对象。

类的声明方式如下:

//声明一个类
class myClass{
    //类中非静态方法中的this指向都是其具体创建的对象
    name: string="我是谁?";
    lover: string = "灵儿";
    readonly say:string="谁都改不了"; //readonly 属性对象创建后只能读取不能修改
    static meOnlyHave: number = 33;//静态属性可以直接通过类调用,但是不能通过对象调用。
    //构造函数,用类创建对象时,一定会调用的方法,通过该方法传入对象具体的细节。
    constructor(name:string,lover:string){
       this.name = name;
       this.lover = lover;
    }
    //声明一个方法
    iLoveDo(a:number,b:number){
        if(a + b == 2){
         console.log("我最爱的两个数字是" + a + "和" + b + "\n因为他们加起来是2" + "我最喜欢的一部动漫的女主的编号" );
    }else {
       console.log(a + b);
    }
    }
}
//声明一个具体的对象
let myClassObject = new myClass("广","灵儿");
myClassObject.iLoveDo;

B、类的继承和抽象类

  • 类的继承
class InMyClass extends myClass{
      //继承了myClass类后,就直接拥有了其父类的方法和属性
      //也可以声明自己的属性和方法
      dream:string = "成为更好的自己!";
      //构造函数中使用super()让创建对象时给父类继承的属性赋值
      constructor(name:string,lover:string,dream:string){
          super(name,lover);
          this.dream = dream;
      }
      doDream(){
        console.log("唯有拼搏努力!");
        //可以在子类方法中通过super调用父类方法,从而强化父类方法
        super.iLoveDo(0,2);
      }
      //(重写)当子类的方法名和父类继承的一样时,子类方法覆盖父类方法
      iLoveDo(a: number, b: number): void {
          console.log("哈哈,我修改了父类方法,我就是王者!")
      }
}
  • 抽象类

抽象类的出现就是为了继承,它不能被创建实例(对象),里面可以定义具体的属性和方法,也可以规定抽象的属性和方法,这些抽象的方法和属性在继承时,必须被继承者重写。

声明:

//声明一个抽象类
abstract class meAndYou{
    //声明抽象属性和方法
    abstract name:string;
    abstract loveGirl(name:string):void;
    //声明具体的方法和属性
    lover: string = "灵儿";
    doThings(name:string){
        console.log("我爱的人是:" + name);
    }

}

C、接口

接口是对类结构进行的一种规范,里面不能进行具体的逻辑书写。

//声明一个接口
interface animal{
    name:string;
    age:number;
    doTo:string;
    isFemale:boolean;
    do(detail:string,animalType:string):void;    
}
//实现接口
class dog implements animal{
    name:string ="Tom";
    age:number=23;
    doTo:string="舔";
    isFemale:boolean= true;
    do(detail:string,animalType:string):void{
        console.log("me");
    }
}

D、属性封装

//封装一个属性
class people{
    private name:string = "托尼";//该属性是私有属性,只能在该类中调用。
    constructor(){

    }
    //通过方法实现外部调用和修改
    getName(){
        return this.name;
    }
    setName(name:string){
        this.name = name;
    }
    //使用getter和setter实现私有属性的发现和修改
    get _name(){
        return this.name;
    }
    set _name(name){
         this.name = name;
    }
}
let toni = new people();
//私有属性不能直接调用
//console.log(toni.name);//报错
toni._name = "水门";//通过setter设置name
console.log(toni._name);
toni.setName("波风"); //通过方法设置name
console.log(toni._name);
//即使在其子类中也不能直接调用
class goodBoy extends people{
       age: number;
       protected lover: string;
       //使用protected修饰的属性只能在自己及子类中使用,不能在实例对象中使用
       constructor(age:number){
        super();
        this.age = age
       }
       getFatherName(){
        // this.name;//报错
        console.log(this._name);
       }
}

E、泛型

为了确认函数输入和输出结果结构的一致性。

//声明一个简单的泛型
function meMe<T>(hh: T):T{
      return hh;
}
//使用
meMe<string>("我是波风水门");
//泛型的继承
function meMeMe<T extends goodBoy>(hh:T): T{     
      return hh;
}
//使用
meMeMe<goodBoy>(new goodBoy(33));

文章来源:https://blog.csdn.net/m0_71774042/article/details/135659456
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。