0
点赞
收藏
分享

微信扫一扫

TypeScript的学习笔记

金穗_ec4b 2022-04-15 阅读 120
typescript

TypeScript

环境搭建

  1. 全局安装 npm i -g typescript
  2. 执行命令 tsc xxx.ts — 这就可以将ts文件转化为js文件了

基本类型

  • 类型声明

    • 语法:

      let 变量: 类型;
      let 变量: 类型 =;
      function fn(参数:类型,参数:类型):类型 {
        // xxx
      }
      
  • 自动类型判断

    • TS拥有自动的类型判断机制
    • 当对变量的声明和赋值是同时进行的,TS编译器会自动判断变量的类型
    • 所以如果你的变量的声明和赋值是同时进行的,可以省略掉类型声明
  • 类型

    类型例子描述
    number1,-33,2,5任意数字
    string‘asd’,‘qwr’任意字符串
    booleantrue,false布尔值ture或false
    字面量其本身限制变量的值就是该字面量的值
    any*任意类型(相当于就是原生js,就是关闭类型检测,其实不写any也可以,默认就是any)
    unknown*类型安全的any
    void空值(undefined)没有值(或undefined)
    never没有值不能是任何值
    object{name: ‘孙悟空’}对象
    array[1,2,3]数组
    tuple[4,5]元素,TS新增类型,固定长度的数组
    enumenum{A, B}枚举,TS中新增的类型
let a: number
a = 10
a = 'hellp'	// a的类型是number,在以后的使用过程只能是数字,此行代码会报错

// 声明完变量直接赋值
let c: boolean = false
// 但是这种情况下可以省略,会自动判断
let c = false

// 这样就可以限制入参的类型了
// 在ts文件里面参数个数多传少传也会报错
// 第三个number表示返回值期望是一个number
fucntion sum(a: number, b: number): number {
  return a + b
}

// 字面量的使用,就是只能是其本省
let a : 10;
a = 10	// 这样a只允许等于10,用的少
let b : 'male' | 'female'	// 这样a可以等于两个,一般这样用

// 还有联合类型
let a: boolean | string // 这样a可以为两种类型

// any和unknow的区别,unknow实际就是一个类型安全的any,不能直接赋值给其他变量
let d: any
let e: unknow
let s: string
s = d	// 此时s也变成any了,any就祸祸别人了
s = e // 这时候会报错,unknow会安全
e = 'unknow'
// 类型断言	可以告诉解析器变量的实际类型
// 下面两种用法都一样
s = e as string;	
s = <string>e

// void,以函数为例
funtion fn(): void {
	// xxx
  return null
  return undefined
  // 不反回都可以
}

// never,表示永远不会返回结果
function fn2(): never {
  throw new Error('报错了')
  // 不反回
}

// object 表示一个对象,如下都可以
let a: object
let a: {}
a = function fn() {}
// 实际我们是为了限制里面的属性,{}这样我们可以指定对象里面可以包含哪些属性
// 语法:{属性名:类型},加上问号表示可选属性
let b: { name:string, age?" number" }
b = { name: '孙悟空' }
// 表示要有a,其他都有多少都行
let c: {name: string, [propName: string] : any}	// 这里propName写啥都行,类似形参。这样有name,其他有啥不管

// 设置函数的结构声明
let d: (a:number,b:number)=>number
d = function (n1: number, n2: number): number {
  return n1 + n2
}

// string[] 表示字符串数组
let e: string[];
e = ['1', '2', '3']
// number[] 表示数值数组
let f: number[];
let f: Array<number>
f = [1,2,3]

// 元组 一个固定长度的数组
let h : [string, strign]

// enum 枚举值
enum Gender{
  Male = 0,
  Feal = 1
}
let i : {name: string, gender: Gender}
i = {
  name: '孙悟空',
  gender: Gender.Male
}

// 连接
let j: {name: string} & {age: number}
j = {name: '孙悟空', age: 18}

// 类型别名
type myType = 1 | 2 | 3 | 4;
let k: myType

编译选项

tscconfig.json文件配置

tsc -w 可以编译文件且实时监控

{
  // 这是ts编译器的配置文件,在根目录里
  "include": ["src/**/*", "tests/**/*"],	// 定义希望被编译文件所在的目录(一个*表示任意文件,两个**表示任意目录)
  "exclude": ["./src/hello/**"],	// 定义需要排除在外的目录(默认是有node_modules,bower——components,jspm——packages)
  "extends": "./configs/base",	// 定义需要被继承的配置文件
  "files": [],	// 指定被编译文件的列表,只有需要编译文件少的时候才会用到
  // 编译器的选项 
  "compilerOptions": {
    "target": "es3",	// 指定编译后js的版本
    "module": "commonjs",	// 指定要使用模块化的规范(none,commonjs,amd,systen,umd,es6)
    "lib": [],	// 指定用到那些库,一般在浏览器运行不用配置
    "outDir": "./dist",	// 编译后文件所在的目录
    "outFile": "./dist/app.js", // 将代码合并为一个文件,所有的全局作用域的代码都合并到一个中
    "allowJs": "false",	// 是否对js文件进行编译,默认为false
    "checkJs": "false",	// 是否检查js语法规范,默认为false,用ts规范检查
    "removeComments": "false",	// 是否移除注释
    "noEmit": "false", // 不生成编译后文件,有时候只是检查一下,不编译
    "noEmitOnError": "false", // 编译有错误不生成编译文件
    "strict": "false", // 所有严格检查的总开关
    "alwaysStrict": "false",	// 编译后的文件是否使用严格模式(如果文件里面有export,import,就不会有use strict,因为前两者就默认是严格模式了)
    "noImplicitny": "false",	// 不允许隐式any类型
    "noImplicitThis": "false",	// 不允许不明确类型的this
    "strickNullChecks": "false",	// 严格的检查空值
  }
}

通过webpack来使用TS打包

  • npm i -D webpack web pack-cli typescript ts-loader
  • 新建webpack.config.js(做好内部的相关配置)
  • 根目录下心间tsconfig.json文件
  • 在package.json里面配置命令,“build”: “webpack” 即可

webpack常用插件

  • HTMLWebpackPlugin 生成html文件
  • Webpack-deb-server 生成一个本地服务器,热启动
  • Clean-webpakc-plugin打包前清除打包出口文件
  • 需要在resolve配置extensions增加ts文件,使得ts文件可以被引入
引入babel ---- 把新语法转换成旧语法
  • @babel/core – babel核心工具
  • @babel/preset-env – babel预先设置的环境
  • babel-loader – 属于把babel和webpack结合的工具
  • core-js – 提供一个更新的js运行环境

Webpack.config.js

// 指定webpack打包时要使用的模块
module: {
  // 指定要加载的规则
	rule" [
		{
      // test指定的事规则生效的文件
      test: /\.ts$/,
      // 要使用的loader,这个use是从后往前执行的
      use: [
        {
          loader: 'babel-loader',
          // 设置巴格莱
          options: {
            // 设置预定义的环境
            presets: [
              // 指定环境的插件
              "@babel/preset-env",
              // 配置信息
              {
                // 兼容的目标浏览器
                targets: {
                  "chorm": "88"
                },
                // 指定corejs的版本
                "corejs": "3",
                // 使用corejs的方式,“usage”表示按需加载
                "useBuiltIns": "usage"
              }
            ]
          }
        }
        'ts-loader'
      ],
      // 要排除的文件
      exclude: /node-modules/
		}
	]
}

面向对象

类(class)

  • 定义类:

    • class 类名 {
        属性名:类型;
        constructor(参数: 类型) {
          this.属性名 = 参数
        }
        
        方法名() {
          // xxx
        }
      }
      
    • 示例:

      class Person {
        // 直接定义的属性是实例属性,需要通过对象的实例去访问
        // 使用static开头的属性是静态属性(类户型),可以直接访问
        // 定义实例属性
        readonly name: string	// 加上readonly就只能读不能改了,不加实例可以改可读
        age: number
        static readonly name: number = 18	// 静态只读属性
        
        // 这里面是实例属性
        // 构造函数会在对象创建时候调用
        constructor(name: string, age: number) {
          // this表示当前的实例
          this.name = name;
          this.age = age
        }
        // 定义实例方法
        sayHello() {
          console.log('say Hello')
          // 在方法中可以通过this来表示当前调用方法的对象
          console.log(this)
        }
        // 定义静态方法
        static sayHello() {
          console.log('say Hello')
        }
      }
      
      const per = new Person()
      

类的继承

/*
*	抽象类(比如上述的Animal,我们希望他不能被直接实例话,因为Animal是用来让别人继承的,就把他归为超类)
*	就在前面加一个abstract,避免他被别人创建对象
* 只有在抽象类中可以添加抽象方法
* 抽象方法,前面加一个abstract,只定义方法的结构
*/
abstract class Animal {
  name: string
  age: number
  
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
  
  abstract sayHello():void;
}
/*
* - extends继承,子类将继承父类的所有方法和属性,不会继承静态属性和方法
*	- 此时,Animal被称为父类,Dog被称为子类
* - 可以将多个类中共有的代码写在一个父类当中,这样只需要写一次
* - 如果在子类中添加了和父类相同的方法,则会覆盖父类的方法,称为方法的重写
*/
class Dog extends Animal {
  
}

class Cat extends Animal {
  age: number;
  constructor(name: string) {
   // 如果在子类写了构造函数,其实就是会将父类的构造函数覆盖掉,所以必须对父类的构造函数进行调用
   super(name)
   this.age = age
	}
  sayHello() {
    console.log('喵喵喵')
    // 在类的方法中,super就表示当前类的父类,也可以理解为父类的实例
    super.sayHello()
  }
}

接口

// 举例 -- 描述对象类型
type myType = {
  name: string,
  age: number
}

// 接口用来定义一个类结构,用来定义一个类中应该包含哪些属性和方法
// 同时也可以当成类型声明去使用,跟上面那个普通的类型声明可以
// 接口定义是可以重复声明,但是type不行
interface myInterface{
  name: string,
  age: number
}
interface myInterface{
  genter: string
}
const obj: myInterface = {
  name: 'xxx',
  age: 18,
  genter: 'male'
}

/*
* 接口可以在定义类的时候去限制类的结构
* 接口中所有的属性都不能有实际的值
* 接口只定义对象的结构,而不考虑实际值
* 在接口中所有的方法都是抽象方法
*/
interface myInter{
  name: string,
  sayHello():void
}
class Myclass implements myInter{
  name: string
  constructor(name: string) {
    this.name = name
  }
  sayHello() {
    console.log('大家好~~')
  }
}

属性

class Person {
  // TS可以在属性前面添加属性修饰符
	public name: string,	// 默认值,可以在任意位置访问修改
  private age: number,	// 私有属性,只能在类的内部进行访问(修改),子类不能访问
  protected gender: string, // 保护属性,就是一个折中,在类里面可以访问,子类也可以访问
  // 可以在类中添加方法可以使得私有属性可以被外部访问
  // 这里跟vue的双向数据绑定原理一致
  getAge() {
    return this.age
  }
  setAge(val: number) {
    if (val >= 0) {
      this.age = val
    }
	}
  constructor(name: string, age: number, public gender: string) {	// 这里可以有个快捷写法,直接在传参定义修饰符
    this.name = name;
    this.age = age
  }
  
  // TS中设置getter方法的一个快捷方式 -- 起1
  get name() {
    return this.name
  }
  set name(value: string) {
    this.name = value
  }
}
const per = new Person('张三', 18)
console.log(per.name)	// 呼1 -- 这样不会改变我们的使用习惯

泛型

/*
*	在定义函数或者是类的时候,如果遇到类型不明确就可以使用泛型
* 使用:<T> 定义一个叫T的类型,也可以叫其他
			然后在后面就是用这个型
			其实本质就是设置一个x一样,前后需要保持一致
*/

function fn<T>(a: T): T {
  return a
}
// 可以直接使用具有泛型的函数
fn(10);	// 不指定,TS可以自己推断
// 对于比较复杂也可以手动指定
fn<string>('hello')	// 指定泛型

// 指定多个泛型
function fn2<T, K>(a: T):K{
  return a.toString()
}
fn2<number, string>(12)

// 如果还想限定泛型的范围
interface Inter{
  length: number,
}
function fn3<T extends Inter>(a: T):number{
  return a.length
}
fn3<Inter>({length: 10})

class MyClass<T> {
  // xxx
}

视频后面还有一个贪吃蛇的项目,可以用于练习

举报

相关推荐

0 条评论