TypeScript学习笔记3 - 接口

131 阅读4分钟

接口

typeScript 的核心原则之一是对值所具有的结构进行类型检查。我们使用接口(Interfaces)来定义对象的类型。`接口是对象的状态(属性)和行为(方法)的抽象(描述)` 

接口可以描述(约定):

  • 普通对象
    • 属性的数据类型
    • 可选属性
      • 属性不全都是必需的。 有些是只在某些条件下存在,或者根本不存在
    • 只读属性
      • 一些对象属性只能在对象刚刚创建的时候修改其值,一旦赋值后再也不能被改变了
  • 函数类型
    • 描述函数类型(参数的类型与返回的类型)
  • 类类型
    • TypeScript 能够用接口来明确的强制一个类去符合某种契约

普通对象

  需求: 创建人的对象, 需要对人的属性进行一定的约束
  id是number类型, 必须有, 只读的
  name是string类型, 必须有
  age是number类型, 必须有
  sex是string类型, 可以没有

下面通过一个简单示例来观察接口是如何工作的:

  /* 
  在 TypeScript 中,我们使用接口(Interfaces)来定义对象的类型
  接口: 是对象的状态(属性)和行为(方法)的抽象(描述)
  接口类型的对象
      多了或者少了属性是不允许的
      可选属性: ?
      只读属性: readonly
  *//* 
  需求: 创建人的对象, 需要对人的属性进行一定的约束
    id是number类型, 必须有, 只读的
    name是string类型, 必须有
    age是number类型, 必须有
    sex是string类型, 可以没有
  */// 定义人的接口
  interface IPerson {
    id: number
    name: string
    age: number
    sex: string
  }
  ​
  const person1: IPerson = {
    id: 1,
    name: 'tom',
    age: 20,
    sex: '男'
  }

类型检查器会查看对象内部的属性是否与IPerson接口描述一致, 如果不一致就会提示类型错误。

可选属性

接口里的属性不全都是必需的。 有些是只在某些条件下存在,或者根本不存在。

  interface Person {
    id: number
    name: string
    age: number
    sex?: string
  }

带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个 ? 符号。

可选属性的好处之一是可以对可能存在的属性进行预定义,好处之二是可以捕获引用了不存在的属性时的错误。

  const person2: IPerson = {
    id: 1,
    name: 'tom',
    age: 20,
    // sex: '男' // 可以没有
  }

只读属性

一些对象属性只能在对象刚刚创建的时候修改其值。 你可以在属性名前用 readonly 来指定只读属性:

  interface Person {
    readonly id: number
    name: string
    age: number
    sex?: string
  }

一旦赋值后再也不能被改变了。

  const person2: IPerson = {
    id: 2,
    name: 'tom',
    age: 20,
    // sex: '男' // 可以没有
    // xxx: 12 // error 没有在接口中定义, 不能有
  }
  person2.id = 2 // error

函数类型

接口能够描述 JavaScript 中对象拥有的各种各样的外形。 除了描述带有属性的普通对象外,接口也可以描述函数类型

为了使用接口表示函数类型,我们需要给接口定义一个调用签名。它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型

  /* 
  接口可以描述函数类型(参数的类型与返回的类型)
  */interface SearchFunc {
    (source: string, subString: string): boolean
  }

这样定义后,我们可以像使用其它接口一样使用这个函数类型的接口。 下例展示了如何创建一个函数类型的变量,并将一个同类型的函数赋值给这个变量。

  const mySearch: SearchFunc = function (source: string, sub: string): boolean {
    return source.search(sub) > -1
  }
  ​
  console.log(mySearch('abcd', 'bc'))

类类型

类类型

类实现接口

与 C# 或 Java 里接口的基本作用一样,TypeScript 也能够用它来明确的强制一个类去符合某种契约。

  /* 
  类类型: 实现接口
  1. 一个类可以实现多个接口
  2. 一个接口可以继承多个接口
  */interface Alarm {
    alert(): any;
  }
  ​
  interface Light {
    lightOn(): void;
    lightOff(): void;
  }
  ​
  class Car implements Alarm {
    alert() {
        console.log('Car alert');
    }
  }

一个类可以实现多个接口

  class Car2 implements Alarm, Light {
    alert() {
      console.log('Car alert');
    }
    lightOn() {
      console.log('Car light on');
    }
    lightOff() {
      console.log('Car light off');
    }
  }

接口继承接口

和类一样,接口也可以相互继承。 这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。

interface LightableAlarm extends Alarm, Light {

}