WIP:TS基础——接口(interface)

TS中的接口

  • 写在之前

    • 或许当我们只需要定义一个对象或类的时候,使用接口对它们进行约束是显得麻烦的,但是当我们需要定义具有同样结构的多个对象或类的时候,接口就体现出它的作用了。
  • 接口有什么作用,什么时候应该使用接口

    • 定义

      • 我们可以先看看接口的定义,接口是对某些数据或方法的约束规则。
    • 其他面向对象编程语言中的接口

      • 接下来我们可以先了解一下其他面向对象的语言,如C++中,接口的作用,在C++中,接口用于规定子类implements接口之后,必须实现接口中规定的变量和方法(相当于是对子类结构的约束)。
    • C++中将接口也看成是一个类,class B : A,表示B派生自A,A是接口。

      WIP:TS基础——接口(interface)_第1张图片

      C++中会将接口定义为虚函数。

      如果需要提供一个getArea接口,那么需要在Shape类中将这个方法定义为虚函数,当class Rectangle派生自接口Shape,那么Rectangle类必须实现getArea这个方法。

    • TS中的接口

      • TypeScript中的接口是一个很灵活的概念,它相当于扩展了类似C++的面向对象编程语言中接口的行为。
        • TS中的接口允许对类的结构进行约束。(类似于C++中规定了类中必须有哪些变量和方法)。
        • TS中的接口也允许对对象(引用类型)的结构进行约束。(规定了对象中必须包含哪些属性)。
    • 什么时候使用接口

      • 当我们需要对引用类型的结构进行约束的时候可以使用接口。
      • 当我们要声明多个类,我们可以首先定义一个接口用来规定这些类必须具有哪些变量、方法。
  • 使用接口对引用类型进行约束

    • 约束对象

      • 一个简单的例子

        interface Person{
          name: string;
          age: number;
        }
        const person1: Person = {
          name: 'aaa',
          age: 1,
        }
        

        接口一般首字母大写。我们首先定义了一个接口Person,然后定义了一个对象perosn1,并规定它的类型是Person,这样person1中就必须包含name属性和age属性了(必须不多也不少)。

      • 如果对象中比接口少了一些属性

        const person1: Person{
          name: 'aaa',
        }
          // index.ts(6,5): error TS2322: Type '{ name: string; }' is not assignable to type 'Person'.
        //   Property 'age' is missing in type '{ name: string; }'.
        

        我们可以看到当对象person1的类型是Person时,如果person1中没有包含Person中有的age属性,那么会出现报错。

      • 如果对象中比接口多了一些属性

        const person1: Person{
          name: 'aaa',
          age: 1,
          gender: 'male',   
        }
        // index.ts(9,5): error TS2322: Type '{ name: string; age: number; gender: string; }' is not assignable to type 'Person'.
        //   Object literal may only specify known properties, and 'gender' does not exist in type 'Person'.
        

        我们可以看到,当多出了Person接口中没有的属性的时候也会出现报错。

      • 如果对象中的属性的类型和接口中的不一致

        const person1: Person{
          name: 123,
          age: 1
        }
        //报错
        

        当person1对象中的属性name的类型和Person接口中定义的不一致的时候,也会报错。

      • 可选的属性

        interface Person{
          name: string;
          age?: number;
        }
        const person1: Person{
          name: 'aaa',
        }
        

        使用 ?我们可以定义可选属性,如上面的例子中,age就是一个可选属性,表示以Person接口为类型约束的对象可以包含age属性,也可以不包含age属性。

      • 任意属性

        interface Person{
          name: string;
          age?: number;
          [key: string]: any;
        }
        const person1: Person = {
          name: 'aaa',
          gender: 'male',
        }
        

        上面的例子中,接口Person通过[key: string]表示key是string类型的,:any表示值可以是任何类型的。

      • 任意属性的常见错误

        interface Person{
          name: string;
          age?: number;
          [key: string]: string;
        }
        const person1: Person = {
          name: 'aaa',
          gender: 'male',
        }
        // index.ts(3,5): error TS2411: Property 'age' of type 'number' is not assignable to string index type 'string'.
        // index.ts(7,5): error TS2322: Type '{ [x: string]: string | number; name: string; age: number; gender: string; }' is not assignable to type 'Person'.
        //   Index signatures are incompatible.
        //     Type 'string | number' is not assignable to type 'string'.
        //       Type 'number' is not assignable to type 'string'.
        

        报错的原因是[key: string]: string同样会对上面的其他属性,如age?: number进行检查,很显然,age?: number不满足[key: string]: string的要求。

      • 只读属性

        interface Person{
          readonly id: number;
          name: string;
          age?: number;
          [key: string]: any;
        }
        const person1: Person = {
          id: 89742435,
          name: 'aaa',
          gender: 'male',
        }
        person1.id = 111;
        // index.ts(14,5): error TS2540: Cannot assign to 'id' because it is a constant or a read-only property.
        

        我们可以使用readonly关键字声明某一个属性是只读的。这样以Person接口为类型约束的对象不能在初始化后修改id这个属性。

    • 使用接口约束函数

      • 一个简单的例子

        interface encrypt{
          (key: string,val: string): string;
        }
        var md5: encrypt = function(key: string,val: string): string{
          ...
          return 'aaa';
        }
        

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