TypeScript

TypeScript

TypeScript是什么?

  • TypeScriptJavaScript的一个超集,支持ECMAScript 6标准(ES6教程)。
  • TypeScript由微软开发的自由和开源的编程语言。
  • TypeScript设计目标是开发大型应用,它可以编译成纯JavaScript,编译出来的 JavaScript可以运行在任何浏览器上。
  • TypeScript本身并非什么高深的技术,凡是有JavaScript基础的同学都可以轻松掌握

TypeScript的特性

  • TypeScript是一种给 JavaScript添加特性的语言扩展。增加的功能包括:
    • 类型批注和编译时类型检查
    • 类型推断
    • 类型擦除
    • 接口枚举
    • Mixin
    • 泛型编程
    • 名字空间
    • 元组
    • Await
  • 以下功能是从ECMA 2015反向移植而来:
    • 模块
    • lambda函数的箭头语法
    • 可选参数以及默认参数

TypeScriptJavaScript的区别

  • TypeScript JavaScript的超集,扩展了JavaScript的语法,因此现有的JavaScript代码可与TypeScript一起工作无需任何修改,TypeScript通过类型注解提供编译时的静态类型检查。
  • TypeScript可处理已有的JavaScript代码,并只对其中的TypeScript代码进行编译。
  • 优势一:类型化思维方式,使得开发更加严谨,提前发现错误,减少改Bug时间。
  • 优势二:类型系统提高了代码可读性,并使维护和重构代码更加容易。
  • 优势三:补充了接口、枚举等开发大型应用时JS缺失的功能。
  • Vue 3源码使用TS重写,释放出重要信号: TS是趋势。
  • Angular默认支持TS; ReactTS美配合,是很多大型项目的首选

TypeScript的安装

  • 有两种主要的方式来获取TypeScript工具:

    • 通过npm(Node.js包管理器) tsc –v查看版本

      • npm:包的管理器

      • install:安装,简写为i

      • global:全局,简写-g

      • 全局安装,当前电脑任意位置都可以使用

        npm install -global typescript
        

        TypeScript_第1张图片

      • 局部安装,当前项目中安装

        // 初始化项目 npm init -y(英文目录) npm init(中文目录)
        npm install typescript
        
    • 安装Visual StudioTypeScript插件

  • 注意:由于Vscode的终端默认使用powershell,默认禁止输入脚本(指令)

    • 解决办法:以管理员身份运行powershell,终端执行set-ExecutionPolicy RemoteSigned;输入y

Hello TypeScript(全局)

  • 通常我们使用.ts作为TypeScript代码文件的扩展名

    • 目录结构:

      TypeScript_第2张图片

    • index.html

      DOCTYPE html>
      <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" />
          <title>Documenttitle>
        head>
        <body>body>
        <script src="./index.js">script>
      html>
      
    • index.ts

      console.log("Hello TypeScript!");
      
    • 使用方式:

    • 打开终端,通过tsc fileName编译转化为js文件(注意你的当前目录所在)

      TypeScript_第3张图片

    • 这个时候你就会发现文件目录多出来一个index.js文件

      TypeScript_第4张图片

    • 打开index.html,控制台打印结果。或者也可以在终端node执行index.js文件

      TypeScript_第5张图片

Hello TypeScript(局部)

  • 创建文件夹typescript

  • 在终端初始化项目npm init -y

    TypeScript_第6张图片

  • 这个时候typescript文件夹下会多出一个package.json文件

    TypeScript_第7张图片

  • 终端局部安装npm install typescript

    TypeScript_第8张图片

  • package.json文件夹里面会多出一个"typescript": "^4.7.2",这个就表示安装的typescript版本是4.7.2

    TypeScript_第9张图片

TypeScript 转换为 JavaScript

TypeScript_第10张图片

TypeScript 转换为 JavaScript

  • 目录结构

    TypeScript_第11张图片

  • index.ts

    console.log("Hello TypeScript!");
    
  • 自动编译TypeScript

    • 安装npm i ts-node-dev --save-dev

    • packages.json中添加脚本

      {
        "name": "typescript",
        "version": "1.0.0",
        "description": "",
        "main": "index.js",
        "scripts": {
          "start": "ts-node-dev --respawn --transpile-only index.ts"
        },
        "keywords": [],
        "author": "",
        "license": "ISC",
        "dependencies": {
          "typescript": "^4.7.2"
        }
      }
      
    • 在终端中使用npm start启动

      TypeScript_第12张图片

    • 这样我们就不需要在修改index.ts的同时还有一直在控制台输入node index.ts,当你修改index.ts保存后它就会自动执行。

TypeScript 构成

  • TypeScript 程序由以下几个部分组成:
    • 模块
    • 函数
    • 变量
    • 语句和表达式
    • 注释

TypeScript 基础类型

类型 例子 描述
number 1,-33,2.5 任意数字
string ‘hi’,“hi”,hi 任意字符串
boolean true、false 布尔值 true 或 false
字面量 其本身 限制变量的值就是该字面量的值
any * 任意类型
unknown * 类型安全的 any
void 空值(undefined) 没有值(或 undefined)
never 没有值 不能是任何值
object {name:“孙悟空”} 任意的 JS 对象
array [1,2,3] 任意 JS 数组
tuple [4,5] 元组,TS 新增类型,固定长度数组
enum enum{A,B} 枚举,TS 中新增类型

TypeScript 基础类型

  • number:双精度64位浮点值。它可以用来表示整数和分数

    // 十进制
    let a: number = 10; // 这里限制了a的数据类型为number
    console.log(a); // 10
    
    // 八进制
    let b: number = 0o744;
    console.log(b); //484
    
    // 二进制
    let c: number = 0b1010;
    console.log(c); // 1010
    
    // 十六进制
    let d: number = 0xf00d;
    console.log(d); // 61453
    

    在这里插入图片描述

TypeScript 基础类型

  • boolean

    let a: boolean = false;
    
    let b: boolean = true;
    
    let c = true;
    
    console.log(a, b, c);
    

    在这里插入图片描述

  • string

    let a: string = "hello";
    
    setTimeout(() => {
      a = "world";
      console.log(a);
    }, 2000);
    
    console.log(a);
    

    在这里插入图片描述

TypeScript 基础类型

  • 字面量:也可以使用字面量去指定变量的类型,通过字面量可以确定变量的取值范围

    // 字面量类型 限制取值范围
    
    // 传的参数的取值只能是 "red" | "green" | "yellow" | "blue" 不能是别的
    const a = (b: "red" | "green" | "yellow" | "blue") => {
      console.log(b); // red
    };
    a("red");
    
    const foo = (n: 10 | 20 | 30 | "red") => {
      console.log(n); // 10
    };
    foo(10);
    
  • any

    // 任意类型
    let a: any = "aaa";
    
    a = 10;
    
    a = false;
    
    console.log(a); // false
    
  • unknown

    // 不知道是什么类型
    let a: unknown = "a";
    
    a = 10;
    
    console.log(a); // 10
    

TypeScript 基础类型

  • tuple

    // tuple 元组 类似js中的数组,它是元素可以是任意类型的
    let x: [number, string];
    
    x = [10, "hello"];
    
  • array

    // array 数组
    
    let arr: Array<any> = [1, 2, 3, "hello", true];
    
    let arr1: Array<number> = [1, 2, 3];
    
    let arr2: Array<Object> = [{ name: "Linux", age: 28 }];
    
    console.log(arr); // [1, 2, 3, "hello", true]
    console.log(arr1); // [1, 2, 3]
    console.log(arr2); // [{ name: "Linux", age: 28 }]
    
  • enum枚举

    // 通常情况下我们使用枚举类型定义一类常量
    enum Color {
      red = "red",
      blue = "blue",
    }
    
    console.log(Color.red); // red
    console.log(Color.blue); // blue
    
    // 枚举类可以作为变量的数据类型
    let a: Color = Color.red;
    // a = '' 警告
    console.log(a); // red
    

TypeScript 基础类型

  • 类型断言(类型转换)

  • 有些情况下,变量的类型对于我们来说是很明确,但是TS编译器却并不清楚,此时,可以通过类型断言来告诉编译器变量的类型,断言有两种形式

    • 第一种

      let a: unknown = "hello ts";
      
      let lg: number = (a as string).length;
      
      console.log(lg); // 8
      
    • 第二种

      let a: unknown = "hello ts";
      
      let lgx: number = (<string>a).length;
      
      console.log(lgx); // 8
      

TypeScript函数(一)

  • 函数定义

    // 普通定义函数方式
    function foo() {
      console.log("foo"); // foo
    }
    foo();
    
    // 声明式
    const bar = function () {
      console.log("bar"); // bar
    };
    bar();
    
  • 函数返回值

    • 我们会希望函数将执行的结果返回到调用它的地方,通过使用return语句就可以实现。

    • 在使用return语句时,函数会停止执行,并返回指定的值。

    • 注意:返回值的类型需要与函数定义的返回类型(return_type)一致

      // function function_name(): return_type {
      //   // 语句
      //   return value;
      // }
      
      function foo(): boolean {
        return true;
      }
      console.log(foo()); // true
      
      function bar(): Object {
        return {
          name: "foo",
          age: 42,
        };
      }
      console.log(bar()); // { name: 'foo', age: 42 }
      
      // 没有返回值
      function bo(): void {}
      bo();
      

TypeScript函数(二)

  • 带参数函数

    • 在调用函数时,您可以向其传递值,这些值被称为参数。

    • 这些参数可以在函数中使用。

    • 您可以向函数发送多个参数,每个参数使用逗号 , 分隔

      function bar(a: number, b: string) {
        console.log(a, b); // 10 hello
      }
      bar(10, "hello");
      
  • 可选参数

    • TypeScript函数里,如果我们定义了参数,则我们必须传入这些参数,除非将这些参数设置为可选,可选参数使用问号标识 ?

    • 可选参数必须跟在必需参数后面。 如果上例我们想让b是可选的,a必选,那么就要调整它们的位置,把b放在后面。如果都是可选参数就没关系。

      // 可选参数 ?
      // 可选参数需要放在固定参数的后面
      function foo(a: number, b?: string) {
        console.log(a, b); // 10 undefined
      }
      foo(10);
      

TypeScript函数(三)

  • 默认参数

    • 可以设置参数的默认值,这样在调用函数的时候,如果不传入该参数的值,则使用默认参数

      // 参数的默认值
      // 参数有了默认值,就可以不传,不传就以默认值为准
      // 传了以实际值为准
      function test(a: number, b: number = 10) {
        console.log(a, b); // 10 10 // 10 20
      }
      test(10);
      test(10, 20);
      
  • 剩余参数

    • 有一种情况,我们不知道要向函数传入多少个参数,这时候我们就可以使用剩余参数来定义。

    • 剩余参数语法允许我们将一个不确定数量的参数作为一个数组传入。

      // 剩余参数
      function boo(a: number, ...args: any[]) {
        console.log(a, ...args); // 10 [ 20, 30, 40 ]
      }
      boo(10, [20, 30, 40]);
      

TypeScript函数(四)

  • 匿名函数(函数表达式)

    const msg = function () {
      return "Hello";
    };
    console.log(msg()); // Hello
    
  • 匿名函数自调用

    (function () {
      console.log("hello");
    })();
    
  • Lambda函数(箭头函数)

    const a = (a: number, c: boolean = false, b?: string): number => {
      console.log(a, b, c); // 10 "hello" true
      return 10;
    };
    a(10, true, "hello");
    

TypeScript 联合类型

  • 联合类型(Union Types)可以通过管道(|)将变量设置多种类型,赋值时可以根据设置的类型来赋值。

    • 注意:只能赋值指定的类型,如果赋值其它类型就会报错。

    • 语法:Type1|Type2|Type3

      let a: number | string;
      
      a = 10;
      
      a = "hello";
      
      console.log(a); // hello
      
  • 联合类型数组

    // 可以放入number类型和string类型的元素
    let b: Array<number | string> = [];
    b = [10, "hello", 20];
    console.log(b);
    
    // 只能同时放入number类型或者string类型
    let c: number[] | string[];
    c = [10, 20];
    console.log(c); // [10, 20]
    c = ["hello", "ts"];
    console.log(c); // [ 'hello', 'ts' ]
    
    const foo = (a: number | string): void => {
      console.log(a); // 10  // hello
    };
    foo(10);
    foo("hello");
    

TypeScript 类(一)

  • TypeScript是面向对象的JavaScript

  • 类描述了所创建的对象共同的属性和方法。

  • TypeScript支持面向对象的所有特性,比如 类、接口等

  • 定义类的关键字为class,后面紧跟类名,类可以包含以下几个模块(类的数据成员):

    • 字段 − 类里面声明的变量。字段表示对象的有关数据。
    • 构造函数 − 实例化时调用,可以为类的对象分配内存。
    • 方法 − 对象要执行的操作。
  • 创建实例化对象

  • 我们定义出来的类是可以作为类型去使用的

    // 创建类
    class Car {
      // 字段[属性、成员变量]
      brand: string;
      timestamp: Date;
      // 构造函数
      // constructor 初始化参数
      constructor(brand: string, timestamp: Date) {
        this.brand = brand;
        this.timestamp = timestamp;
      }
      // 方法(普通函数)
      disp(): void {
        console.log(`品牌:${this.brand}`);
      }
      // 箭头函数
      sayHi = (name: string): string => {
        console.log(name); // hello
        return name;
      };
    }
    
    // 创建对象的方式一
    const car = new Car("法拉利", new Date());
    console.log(car.brand, car.timestamp); // 法拉利 2022-05-26T10:36:54.145Z
    car.disp(); // 品牌:法拉利
    car.sayHi("hello");
    
    // 创建对象的方式二
    const baoma: Car = {
      brand: "宝马",
      timestamp: new Date(),
      // 重写方法
      disp() {},
      sayHi(): string {
        return "";
      },
    };
    baoma.disp();
    
    const foo = (car: Car) => {
      console.log(car);
      // Car {
      //   sayHi: [Function (anonymous)],
      //   brand: '法拉利',
      //   timestamp: 2022-05-28T02:08:48.847Z
      // }
    };
    foo(new Car("法拉利", new Date()));
    

TypeScript 类(二)

  • static关键字

    • static关键字用于定义类的数据成员(属性和方法)为静态的,静态成员可以直接通过类名调用

      // 被 static 修饰的方法和属性 叫做静态方法和静态属性
      // 静态方法和属性 在使用的时候需要被类直接调用 不需要实例化(不需要创建对象)
      class Person {
        static title = 10;
        static sayHi() {
          console.log("Hello"); // Hello
        }
      }
      
      console.log(Person.title); // 10
      
      // 可以赋值
      console.log((Person.title = 20)); // 20
      
      Person.sayHi();
      
  • instanceof运算符

    • instanceof运算符用于判断对象是否是指定的类型,如果是返回true,否则返回false
  • 访问控制修饰符

  • TypeScript中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。TypeScript支持3种不同的访问权限

    • public(默认) : 公有,可以在任何地方被访问。(写或不写都是public
    • protected: 受保护,可以被其自身以及其子类和父类访问。
    • private: 私有,只能被其定义所在的类访问

TypeScript 类的继承

  • TypeScript支持继承类,即我们可以在创建类的时候继承一个已存在的类,这个已存在的类称为父类,继承它的类称为子类。

  • 类继承使用关键字extends,子类除了不能继承父类的私有成员(方法和属性)和构造函数,其他的都可以继承。

  • TypeScript一次只能继承一个类,不支持继承多个类,但TypeScript支持多重继承(Student 继承 PersonChildren 继承 Student)。

  • 继承类的方法重写

  • 类继承后,子类可以对父类的方法重新定义,这个过程称之为方法的重写。

  • 其中super关键字是对父类的直接引用,该关键字可以引用父类的属性和方法。

    class Person {
      name: string;
      age: number;
    
      constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
      }
    
      sayHi = (): void => {
        console.log(`${this.name}:我今年 ${this.age}`);
      };
    }
    
    class Student extends Person {
      constructor(name: string, age: number) {
        super(name, age);
      }
    }
    
    class Children extends Student {
      constructor(name: string, age: number) {
        super(name, age);
      }
      // 方法也可以被重写
      sayHi = (): void => {
        console.log("hi");
      };
    }
    

TypeScript抽象类

  • 什么是抽象类?
    • abstract修饰的类,就是抽象类,抽象类又叫基类(父类)
    • 证明只能作为父类使用,不能作为子类使用
    • abstract修饰的方法叫做抽象方法,被abstract修饰的属性叫做抽象属性,抽象类在被被继承时,抽象方法和抽象属性必须重写
  • 为什么要有抽象类?
    • 为了规定类中的一些属性和方法,在被继承的时候必须重写,所以被abstract修饰的方法和属性,在继承时必须重写,分别叫做抽象类和抽象方法
  • 抽象类的特点:
    • 抽象类自身无法实例化,必须由子类(派生类)进行实例化
    • 抽象类也可以拥有自己的抽象方法和属性
    • 抽象类中的抽象方法和抽象属性必须被重写

TypeScript抽象类的定义与使用

abstract class Animal {
  abstract name: string;

  // 抽象方法不能有方法体
  abstract speak(): void;
  abstract say: () => void;
}

class Dog extends Animal {
  // 抽象类在被被继承时,抽象方法和抽象属性必须重写
  name: string;
  constructor(name: string) {
    super();
    this.name = name;
  }
  speak(): void {
    console.log(`${this.name}:汪汪汪`);
  }
  say = () => void {};
}

const dog = new Dog("泰迪");
console.log(dog);
dog.speak();

TypeScript_第13张图片

TypeScript接口

  • 接口定义使用interface关键字

  • 接口的作用类似于抽象类,不同点在于接口中的所有方法和属性都是没有实值的,换句话说接口中的所有方法都是抽象方法。接口主要负责定义一个类的结构,接口可以去限制一个对象的接口,对象只有包含接口中定义的所有属性和方法时才能匹配接口。同时,可以让一个类去实现接口,实现接口时类中要保护接口中的所有属性

  • 需要注意接口不能转换为 JavaScript。 它只是TypeScript的一部分。

    interface IPerson {
      firstName: string;
      lastName: string;
    
      sayHi: () => void;
    }
    
    const customer: IPerson = {
      firstName: "Tom",
      lastName: "Hanks",
      sayHi: (): string => {
        return "Hi there";
      },
    };
    
    interface IA {
      a: string;
    }
    
    // 类实现接口 同时实现多个接口
    class Student implements IPerson, IA {
      firstName: string;
      lastName: string;
      a: string;
    
      constructor(firstName: string, lastName: string, a: string) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.a = a;
      }
      sayHi = (): void => {
        console.log(`${this.firstName}${this.lastName}`);
      };
    }
    
    const stu = new Student("王", "五", "好");
    stu.sayHi();
    

实现接口

  • 接口的实现使用implements关键字

  • 同一个类可以实现多个接口

  • 抽象类也可以实现接口

  • 接口不能实现接口,但可以使用extends扩展

    interface IPerson {
      firstName: string;
      lastName: string;
    }
    
    // 接口可以被扩展
    interface IB extends IPerson {
      age: number;
    }
    
    class Student implements IB {
      age: number;
      firstName: string;
      lastName: string;
    }
    

泛型

  • 在定义函数和类时,遇到类型不明确的时候就可以使用泛型

  • 泛型可以指定多个

    class Person {
      name: string;
      age: number;
      constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
      }
    }
    
    // T 可以是任意字符  一般使用 T K V
    function foo<T>(a: any) {
      console.log(a);
    }
    
    const p = new Person("张三", 20);
    
    foo<Person>(p);
    
    foo<Number>(10);
    

    TypeScript_第14张图片

你可能感兴趣的:(TS,typescript,javascript)