• typescript学习(二)


    这里记录下Typescript第二部分的学习,重点注意下接口以及函数’

    四 接口

    1.接口的基本使用

    • 什么是接口?

      接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,

      然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法

    • 格式:

    interface interface_name {}

    type 名称 = {}

    /* 
    接口是什么?
      接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,
      然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法 
    
      接口也是一种数据类型
    
    格式:
      interface interface_name { 
      }
    */
    
    interface IFullName {
      firstName: string
      lastName : string
    }
    
    let goddassName: IFullName = {
      firstName: "邱",
      lastName: "淑贞"
    }
    
    console.log(goddassName.firstName);
    console.log(goddassName.lastName);
    
    
    
    function say({firstName, lastName}:IFullName):void {
      console.log(`我的姓名是:${firstName}_${lastName}`);
    }
    say(goddassName);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    2.可选属性与只读属性

    • 可选属性使用: ?
    • 只读属性使用: readonly
    • readonly与const的区别: 做为变量使用的话用 const,若做为属性则使用readonly
    export default {}
    
    
    // 可选属性   使用?来进行修饰
    interface IFullName {
      firstName: string
      lastName : string
      age?: number
    }
    
    let goddassName: IFullName = {
      firstName: "邱",
      lastName: "淑贞"
    }
    
    console.log(goddassName.firstName);
    console.log(goddassName.lastName);
    
    
    // 只读属性  readonly
    interface IInfo {
      readonly uname: string;
      readonly uage: number;
    }
    
    let beauty:IInfo = {
      uname: "邱淑贞",
      uage: 18
    }
    
    // beauty.uname = "赵丽颖";  // 报错
    
    /* 
      总结: readyonly 与 const 区别:
        最简单判断该用readonly还是const的方法是看要把它做为变量使用还是做为一个属性。 
        做为变量使用的话用 const,
        若做为属性则使用readonly
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    3.索引签名

    • 定义: 索引签名用于描述那些“通过索引得到”的类型
    • 格式: 如[props: string]:any
    • 应用场景: 解决参数问题

    当需要传入的参数多个且不确定的时候需要(疑问,为什么不用any,当传入且不确定any不是更好

    4.函数接口

    • 为了使用接口表示函数类型,我们需要给接口定义一个调用签名。

    ​ 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。

    export default {}
    
    // 函数接口
    /* 
      为了使用接口表示函数类型,我们需要给接口定义一个调用签名。 
      它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型
    */
    
    interface ImakeMoney {
      (salary:number, reward:number):number
    }
    
    
    let sum:ImakeMoney = function (x:number, y:number):number {
      return x + y;
    }
    let res = sum(10, 20);
    console.log(res);
    
    
    // 接口与数组
    // 我们定义了StringArray接口,它具有索引签名。 
    // 这个索引签名表示了当用 number去索引StringArray时会得到string类型的返回值
    interface IStringArray {
      [index: number]: string;
    }
    
    let myArray: IStringArray;
    myArray = ["邱淑贞", "赵今麦"];
    
    let myStr: string = myArray[1];
    console.log(myStr);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    可以通过实现函数的方式来实现函数接口,这里还演示了通过标注未number的方式可以拿到索引的下标

    5.接口的继承

    接口继承就是说接口可以通过其他接口来扩展自己。

    • Typescript 允许接口继承多个接口。
    • 继承使用关键字 extends。
    // 单继承
    interface IPerson { 
      age:number 
    } 
    interface IName extends IPerson { 
      name:string 
    } 
    
    let lady:IName = {
      name: "邱淑贞",
      age: 18
    }
    
    // 多继承
    interface IFatherMoney {
      m1: number
    }
    interface IMotherMoney {
      m2: number
    }
    
    interface ISon extends IFatherMoney, IMotherMoney {
      s: number
    } 
    
    let money:ISon = {
      m1: 100,
      m2: 100,
      s: 100
    }
    
    
    console.log(`儿子一共有${money.m1 + money.m2 + money.s}万元`);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    6.接口的混合类型

    比较一下接口和别名的区别

    先不要看默认比较一下两者的共同点和不同点。
    一、两者都可以实现类似于限定类型的效果。
    Type别名是

    export default {}
    
    // 第一种
    type beautys = "邱淑贞" | "赵雅芝" | "王祖贤" | "朱茵"
    let one:beautys;
    
    one = "邱淑贞";
    // one = 100 // 报错
    
    
    // 第二种
    type myfun = (a:number, b:number) => number;
    
    let fun:myfun = (a:number, b:number) => a + b;
    fun(10, 20);
    
    
    // 第三种
    type myGoddass = {
      name: string,
      age: number,
      sex: string,
      actor?: boolean
    }
    
    let shuzhen:myGoddass = {
      name: "邱淑贞",
      age: 18,
      sex: "女"
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    而接口的基本使用类似于这样

    /* 
    接口是什么?
      接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,
      然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法 
    
      接口也是一种数据类型
    
    格式:
      interface interface_name { 
      }
    */
    
    interface IFullName {
      firstName: string
      lastName : string
    }
    
    let goddassName: IFullName = {
      firstName: "邱",
      lastName: "淑贞"
    }
    
    console.log(goddassName.firstName);
    console.log(goddassName.lastName);
    
    
    
    function say({firstName, lastName}:IFullName):void {
      console.log(`我的姓名是:${firstName}_${lastName}`);
    }
    say(goddassName);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    两者的异同
    都可以通过类似规定类型的方式来实现,但是接口似乎更灵活一些

    1.相同点:

    • 都可以描述属性或方法
    • 都允许拓展

    2.不同点:

    • type可以声明基本数据类型,联合类型,数组等; interface只能声明变量
    • 当出现使用type和interface声明同名的数据时;type会直接报错;interface会进行组合
    • type不会自动合并;interface会
    // 相同点:
    // 1.都可以描述属性或方法
    type womenStar = {
      name: string
      age: number
      perform(): any
    }
    interface IWStar {
      name: string
      age: number
      perform(): any
    }
    
    let star1 = {
      name: "邱淑贞",
      age: 18,
      perform() {
        return "倚天屠龙记"
      }
    }
    let star2 = {
      name: "李一桐",
      age: 18,
      perform() {
        return "射雕英雄传"
      }
    }
    
    // 2.都允许拓展
    type money  = {
      y1: number
    }
    type money2 = money & {
      y2: number
    }
    
    let salary:money2 = {
      y1: 10,
      y2: 20
    }
    
    interface Istar1 {
      name: string
    }
    interface Istar2 extends Istar1 {
      age: number
    }
    
    let starInfo:Istar2 = {
      name: "邱淑贞",
      age: 18
    }
    
    
    // 不同点:
    // 1.type可以声明基本数据类型,联合类型,数组等
    //   interface只能声明变量
    type age = number;
    type info = string | number | boolean;
    type beautyList = [string | number];
    // interface Iage = number; // 报错
    
    
    // 2.当出现使用type和interface声明同名的数据时
    //   type会直接报错
    //   interface会进行组合
    // type mygoddassName = {
    //   name: string
    // }
    
    // type mygoddassName = {
    //   name: number
    // }
    
    interface mygoddassName {
      name: string
    } 
    interface mygoddassName {
      name: string
      age: number
    } 
    
    let goddass:mygoddassName = {
      name: "赵丽颖",
      age: 20
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    五、函数

    1.函数的基本使用

    • 介绍

      函数是JavaScript应用程序的基础。 它帮助你实现抽象层,模拟类,信息隐藏和模块。 在TypeScript里,虽然已经支持类,命名空间和模块,但函数仍然是主要的定义 行为的地方。 TypeScript为JavaScript函数添加了额外的功能,让我们可以更容易地使用

    export default {}
    
    // 匿名函数
    const makeMoney = function(salary: number, reward: number): number {
      return salary + reward
    }
    
    
    // 有名函数 | 命名函数 | 普通函数
    function writeCode(hour: number, sleep: number) {
      return hour
    }
     
    
    // 箭头函数
    const seeMeiMei = (time: number):void => {
      console.log(`我每天要看${time}个小时MeiMei`);
      
    }
    
    seeMeiMei(8)
    
    
    // 接口函数
    type myFunc = (x: number, y: number) => number
    
    const myfunc:myFunc = (a: number, b: number) => a + b
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    2.函数参数的处理

    • 可选参数:
      在 TypeScript 函数里,如果我们定义了参数,则我们必须传入这些参数,除非将这些参数设置为可选,可选参数使用问号标识 `?
    • 默认参数:
      我们也可以设置参数的默认值,这样在调用函数的时候,如果不传入该参数的值,则使用默认参数,语法格式为 ```
    function function_name(param1[:type],param2[:type] = default_value) { 
    }
    
    • 1
    • 2

    剩余参数:

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

    剩余参数语法允许我们将一个不确定数量的参数作为一个数组传入。...args:any[]

    // 可选参数
    const func1:(x: number, y?: number)=>number = function(a, b) {
        return a;
      }
      
      
      const func2 = function(a: number, b?: number): number {
        return a;
      }
      
      func2(10);
      func2(10, 20);
      func2(10, undefined);
      
      
      // 函数的默认值
      const func3 = function(a: number = 1, b:number =2, c:number=3) {
        return a + b + c;
      }
      
      func3();
      func3(10);
      func3(10, 20);
      func3(10, 20, 30);
      
      
      // 函数的剩余参数
      const func4 = function(...args:any[]) {
        console.log(args);
        
      }
      
      func4(10, 20 , 30, "邱淑贞");
      
      const func5 = function(a:number, b:number, ...args:any[]) {
        console.log(a);
        console.log(b);
        console.log(args);
        
      }
      
      func5(10, 20 , 30, "邱淑贞", "邢菲");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    3.构造函数

    TypeScript 也支持使用 JavaScript 内置的构造函数 Function() 来定义函数:

    语法格式如下:

    var res = new Function ([arg1[, arg2[, ...argN]],] functionBody)
    
    • 1

    参数说明:

    • arg1, arg2, … argN:参数列表
    • functionBody:一个含有包括函数定义的 JavaScript 语句的字符串。

    4.函数重载

    重载是方法名字相同,而参数不同,返回类型可以相同也可以不同。

    每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

    参数类型不同:

    function disp(string):void;
    function disp(number):void;

    参数数量不同:

    function disp(n1:number):void;
    function disp(x:number,y:number):void;

    参数类型顺序不同:

    function disp(n1:number,s1:string):void;
    function disp(s:string,n:number):void;

    如果参数类型不同,则参数类型应设置为 any

    参数数量不同你可以将不同的参数设置为可选。

    
    // 不使用函数重载的问题
    function add(a: number, b: number){
      return a + b;
    }
    
    add(10, 20);
    
    
    function add2(a: string, b: string){
      return a + b;
    }
    
    add2("我的女神是: ", "邱淑贞");
    
    
    
    function add3(a: string| number, b: string | number){
      // return a + b;
      if( typeof a=="number" && typeof b=="number"){
        return a + b;
      }
      if( typeof a=="string" && typeof b=="string"){
        return a + b;
      }
      if( typeof a=="string" && typeof b=="number"){
        return a + b;
      }
      if( typeof a=="number" && typeof b=="string"){
        return a + b;
      }
    }
    
    add3("我的女神是: ", "邱淑贞");
    add3(10, 20);
    add3("邱淑贞", 20);
    
    
    // 定义函数重载
    function addFunc(a:number, b: number):number;
    function addFunc(a:string, b: string):string;
    function addFunc(a:number, b: string):string;
    function addFunc(a:string, b: number):string;
    
    
    // 使用函数重载
    function addFunc(a: any, b: any):any {
      return a + b;
    }
    addFunc(10, 20);
    addFunc("谭松韵", "金晨");
    addFunc(27, "白鹿");
    addFunc("赵今麦", 19);
    
    
    // 定义参数类型与参数数量不同
    function star(s1:string):void; 
    function star(n1:number,s1:string):void; 
     
    function star(x:any,y?:any):void { 
        console.log(x); 
        console.log(y); 
    } 
    star("王心凌"); 
    star(1,"爱你");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    5.this的使用

    • JavaScript里,this的值在函数被调用的时候才会指定。 这是个既强大又灵活的特点,但是你需要花点时间弄清楚函数调用的上下文是什么。 但众所周知,这不是一件很简单的事,尤其是在返回一个函数或将函数当做参数传递的时候。

    • 从 TypeScript 2.0 开始,在函数和方法中我们可以声明 this 的类型,实际使用起来也很简单

    • 使用this参数,改变指向

    • 传入this参数,禁止调用this

    let userInfo = {
      name: "邱淑贞",
      age: 18,
      song: "恨你太无情",
      marry: true,
      show: function () {
        this.marry = false;
      },
    };
    
    
    
    class Rectangle1 {
      private w: number;
      private h: number;
    
      constructor(w: number, h: number) {
        this.w = w;
        this.h = h;
      }
    
      getArea() {
        return () => {
          return this.w * this.h;
        };
      }
    }
    
    class Rectangle2 {
      private w: number;
      private h: number;
    
      constructor(w: number, h: number) {
        this.w = w;
        this.h = h;
      }
    
      getArea(this: Rectangle2) {
        return () => {
          return this.w * this.h;
        };
      }
    }
    
    // class Rectangle3 {
    //   private w: number;
    //   private h: number;
    
    //   constructor(w: number, h: number) {
    //     this.w = w;
    //     this.h = h;
    //   }
    
    //   getArea(this: void) {
    //     return () => {
    //       return this.w * this.h;
    //     };
    //   }
    // }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    6.特殊的函数返回值

    • 如果使用类型别名,定义了一个返回值为void的类型, 我们在函数使用的时候,并非一定不能有返回值。

      相反,如果我们在函数中写了返回值,我们的返回值是有效的。

    • 如果我们定义函数的时候明确指出,返回值为void,那么我们将除undefined 和 null 以外的值进行返回都会进行报错

    
    }
    
    let f1 = func1();
    let f2 = func2();
    console.log("f1: ", f1);
    console.log("f2: ", f2);
    
    
    
    // 注意点: 如果我们定义函数的时候明确指出,返回值为void,
    // 那么我们将除undefined 和 null 以外的值进行返回
    
    
    function func3():void {
      // return 123 // 报错
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    MAC Address
    稻草熊娱乐股价再创新低:年内累计跌幅达80%,赵丽颖曾是其股东
    Pydantic:数据类型确认和解析神器
    因为manifest.json文件引起的 android-chrome-192x192.png 404 (Not Found)
    计算机毕业设计Java保险公司管理系统(源码+系统+mysql数据库+lw文档)
    Spring Framework :WebClient 取代 RestTemplate
    tvm在linux环境下的安装与编译及vscode如何配置tvm的远程连接调试环境
    21天经典算法之希尔排序
    Swift 中的动态成员查找
    使用Java操作Redis
  • 原文地址:https://blog.csdn.net/weixin_45953482/article/details/126208632