TS

作者: 张_何 | 来源:发表于2023-01-27 11:36 被阅读0次
    • TypeScript 由微软研发,以JavaScript为基础构建的语言,它是js的一个超集,可以在任何支持js的平台中执行,但它不能被js解析器直接执行,需要经过编译成js执行,ts扩展了js
    • ts添加了类型
    • ts 支持ES的新特性
    • 添加ES不具备的新特性
    • 丰富的配置选项,可以支持特定版本的es
    开发环境
    • 使用tsc ***.ts命令可以将ts文件编译成js

    • 定义变量格式:let 变量名: 类型 = 初始值;

    • 类型名首字母小写:string, number, boolean

      类型
    • 函数定义格式

    function 函数名(参数名:参数类型, 参数名:参数类型): 返回值类型 {
    
    }
    
    • 如果变量的声明和赋值同时进行,ts会自动对变量进行类型检测
    • 可以直接使用字面量进行类型声明let 变量名: 字面量值, 比如:let a: 10,就是指定a的值只能是10, 如果给a赋值别的值,会报错,比如 a=11;就会报错. 这种常用于使用 | 连接多个值给字面量赋值,比如 let b: "male" | "female";这样定义后 b的值只能是"male" 或者 "female"而不能是其他值
    • 使用 | 连接多个类型称为联合类型, 比如 let c: boolean | string; 定义了一个变量c ,这个c 只能赋值boolean或string类型的值
    • any 表示是任意类型,相当于关闭了TS的类型检测, 声明一个变量,不指定类型,没有赋初始值的时候,默认就是any类型
    • unknown 表示类型安全的any, 它于any的区别在于any类型的变量可以赋值给任何类型的变量, 而unknow类型的变量不能赋值给其他类型的变量,
    let s:string="a";
    let u:unknown;
    u = "str";
    s = u; // 报错,不能将unknown类型的变量赋值给string类型的变量
    // 可以通过下面的方式赋值
    if(typeof u==="string"){ 
      s = u;
    }
    // 也可以通过下面类型断言的方式赋值
    s = u as string;
    s = <string>u;
    
    • 类型断言有两种方式:
      • 一种是: 变量 = unknown类型变量 as 变量的类型;, 比如 s = u as string;
      • 一种是: 变量 = <变量类型>unknown类型变量;,比如 s = <string>u;
    • never: 表示永远不会返回结果
    • 属性名后面加?表示该属性是可选属性, 有也可以没有也可以,如下:
      let b:{name: string, age?: number}
      b = {name:'孙悟空'}; //可以
      b = {name:'孙悟空', age:18}; //可以
      b = {name:'孙悟空', age:18, gender:'male'}; //不可以
    • 任意类型属性: 对象中使用[: string]: any, 表示任意类型的属性都可以,可以随便写, string指的是属性的key使用string类型, any表示属性可以是任意类型,比如
      let c: {name: string, [propsName: string]:any}
      c = {name:"孙悟空", age:18, gender:"female"};//可以
      c = {age=18,gender="female"};// 不可以,其他属性随意,但必须要有name属性
    • 数组的两种表达方式:
      • 一种是: 类型[], 比如:let e: string[] = ['a','b','c'];
      • 一种是: Array<类型>, 比如: let g: Array<number> = [1,2,3];
    • 元祖, 就是固定长度的数组
      let h: [string, string];
      h = ["hello","world"];//可以
      h = ["hello","world","!"];//不可以, 长度不对
      h = ["hello"];//不可以, 长度不对
      h = ["hello",123];//不可以, 元素类型不对
    • 枚举
    • & 用法, 表示同时满足
      let j: {name:string} & {age:number};
      j = {name:""孙悟空} & {age:18}; // 可以
      j = {name:""孙悟空} ; // 不可以,没有满足{age:number}
      j = {age:18} ; // 不可以,没有满足{name:string}

    tsconfig.json 配置

    • 使用 type 定义类型别名 type myType = string, myType就相当于string, 通常给联合类型设置别名type myType = 1 | 2 | 3 | 4 | 5;
    • tsc ***.ts -w ,加上-w后会自动监视文件的变化,不用每次都执行tsc ***.ts进行编译产生js文件, 这种方式也很麻烦,如果我们有100个ts文件在改动,那么需要执行一百次这个命令去监视一百个文件的改动
    • 在根目录执行tsc 命令会一次性编译所有的ts文件
    • 我们可以通过在根目录配置tsconfig.json文件的方式,来配置需要编译的文件信息,tsconfig.json 是ts编译器的配置文件,ts编译器可以根据它里面的配置信息来对代码进行编译
    • ts 编译器不会将导入的但没用到的变量编译成js的
    include
    • include 用来指定哪些ts文件需要被编译,如果为空,表示所有ts文件需要编译
    "include" : [
      "./src/**/*"    //这里两个*表示任意目录,一个*表示任意文件
    ]
    
    exclude
    • exclude用来指定哪些ts文件不需要编译
    "exclude" : [
      "./src/hello/**/*"    //这里表示src/hello目录下的所有ts文件都不需要编译
    ]
    
    extends
    • extends 定义被继承的配置文件, 比如别的地方已经有一个***.json文件里配置的需要编译的文件信息,那么就可以使用extends将别的文件里的配置信息继承过来, 比如
    "extends": "./configs/base"
    
    files
    • files 指定被编译文件的列表,只有需要编译的文件少时才会用到,比如
    "files":[
      "core.ts",
      "sys.ts",
      "types.ts",
      ...
    ]
    
    compilerOptions
    • target: 用来指定编译为ES的版本 "target": "es3" // 指定编译为ES3 版本, target 值不能是随意的,只能是指定的 'es3','es5','es6','es2015','es2016','es2017','es2018','es2019','es2020','esnext',如果不是,编译后会提示
    • module: 指定要使用的模块化的规范, "module":"es2015"
    • lib: 用来指定项目中要使用的库,默认["es6","dom"]一般不需要改
    • outDir: 用来指定编译后文件所在目录, "outDir":"./dist"
    • outFile: 可以将我们所有的全局作用域的代码合并为一个文件,"outFile":"./dist/app.js"
    • allowJs: 是否对js文件进行编译,默认是false, "allowJs":false
    • checkJs: 是否检查js代码是否符合语法规范,默认是false,"checkJs":false
    • removeComments: 是否移除注释
    • noEmit: 不成编译后的文件,true 表示不生成,false 表示生成
    • noEmitOnError: 有错误时不生成编译后的文件,true表示不生成,false表示生成
    • alwaysStrict: 用来设置编译后的文件是否使用严格模式,默认false
    • noImplicitAny: 不允许隐式的any类型,默认false
    • noImplicitThis: 不允许不明确类型的this,默认false
    • strictNullChecks: 严格的检查空值
    • strict: 所有严格检查的总开关

    webpack 打包ts代码
    • 使用 npm init -y 命令在根目录下生成package.json文件
    • 使用 npm i -D webpack webpack-cli typescript ts-loader 命令安装webpack和依赖的包, i 表示安装, -D表示开发依赖, webpack-cli是webpack的命令行工具 , typescript 是ts的核心包,ts-loader是webpack的加载器,通过ts-loader可以把我们的ts代码和webpack进行整合
    • 新建webpack.config.js
    const path = require('path') // 引入path包
    const HTMLWebpackPlugin = require('html-webpack-plugin'); //引入html 插件
    const CleanWebpackPlugin = require('clean-webpack-plugin'); //引入插件
    // webpack 中的所有配置信息都应该写在module.exports中
    module.exports = {
      // 指定入口文件
      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/
          }
        ]
      }
      plugins:[
        new HTMLWebpackPlugin(
          options:{
            title:"自定义title"
          }
        ),
        new CleanWebpackPlugin(),
      ],
      // 用来设置引用模块
      resolve: {
        extensions: [ '.ts', '.js'], // 凡是以ts,js 结尾的文件都可以作模块使用
      }
    }
    
    • 创建tsconfig.json指定ts的编译规范

    • 在package.json文件的scripts中,加入"build":"webpack"

    • 执行npm i -D html-webpack-plugin 这个插件自动帮我生成html文件,并引入相关资源,

    • 执行npm i -D webpack-dev-server,安装webpack的开发服务器,它可以根据项目的改变自动刷新, 安装完成后需要在package.json文件的scripts中,加入"start":"webpack server --open chrome.exe"

    • 执行npm i -D clean-webpack-plugin ,它可以帮我们在每次编译前将dist文件清空, 然后将编译的最新的文件放进去,这样可以保持dist下的文件避免有旧文件的情况

    • bable 可以将我们新版本的es转换成低版本的,将浏览器不支持的高版本的新特性转换成浏览器兼容的低版本实现


    • 通过static 关键字可以定义类属性(静态属性),通过类访问
    • readonly 修饰的属性是只读属性
    • 方法不需要使用function 修饰,直接方法名+()+{} 就可以了, 如果是static修饰的是类方法
    • public 修饰的属性可以在任意位置访问, 属性默认是public的
    • private 修饰的属性只能在类内访问, 类外访问会报错,子类也不行, 但如果不修改也可以被访问到,因为ts转换成js的时候会转换成可以访问的
    • protected 修饰的属性只能在该类和子类中访问,其他地方不能访问
    • 可以通过 用get 修饰来实现get 方法,比如:
    class Person {
      constructor(name:string) {
        this._name = name;
      }
      private _name:stirng;
      get name() { // 注意这里没有下划线, 调用的时候可以直接Person对象.name
        return this._name;
      }
      set name(value: string) {
        this._name = name;
      }
    }
    const p = Person()
    console.log(p.name); //通过.name调用get方法访问
    p.name = "***"; //通过.name调用set方法赋值
    
    • 属性的方便写法
    class C{
      // 直接将属性定义在构造函数中
      constructor(public name:string, public age:number){}
    }
    
    // 等同于
    class C{
      public name:string;
      public age:number;
      constructor(name:string, age:number){
        this.name= name;
        this.age = age;
      }
    }
    
    抽象类
    • 用abstract 修饰的类是抽象类,不能用来创建对象,是专门用来被继承的,抽象类中可以添加抽象方法
    • 抽象类中使用abstract 修饰的方法,称为抽象方法,抽象方法没有具体的实现,需要继承的子类自己实现,抽象方法只能定义在抽象类中,并且子类必须对抽象方法进行重写
    接口
    • 接口用来定义类的结构,用来定义一个类中应该包含哪些属性和方法,可以当成类型声明去使用
    • 可以定义多个重名的接口, ts会把重名的接口进行合并
    • 接口可以在定义类的时候去限制类的结构
    • 接口中的所有属性都不能有实际值,也不能有方法的实现, 接口只是定义类的结构
    • 接口是让类去实现的, 实现接口就是使类满足接口的要求, 类实现接口使用关键字 implements; class MyClass implements myInterface { }
    • 接口与抽象类的区别是, 抽象类中可以有普通方法也可以有抽象方法, 而接口中只能有抽象方法, 抽象类是被继承的,接口是被实现的
    泛型
    • 定义函数或是类时,如果遇到类型不明确的就可以使用泛型
    • 泛型可以同时指定多个
    function fn2<T,K>(a:T, b:K): T{
      return a;
    }
    
    • 也可以限制泛型的类型,使用extends限定泛型T必须是Inter的实现类或子类, 这里Inter可以是接口也可以是抽象类,或普通类
    interface Inter{
      length: number;
    }
    
    function fn<T extends Inter>(a: T): number{
      return a.length;
    }
    

    相关文章

      网友评论

          本文标题:TS

          本文链接:https://www.haomeiwen.com/subject/nuwbcdtx.html