zoukankan      html  css  js  c++  java
  • typescript中的接口

    TypeScript的核心原则之一是对值所具有的结构进行类型检查,而接口就是用来定义值的结构,接口自身当作类型来用。

    基本使用

    先看一段代码:

    function func(obj: { name: string }): void {
      console.log('hello ' + obj.name)
    }

    很明显,函数func要求参数是一个包含name属性的对象,name值为string类型。而 { name: string } 就可以被定义为接口,如下:

    interface objType { // 定义接口 objType
      name: string
    }
    
    function func(obj: objType): void {
      console.log('hello ' + obj.name)
    }

    代码里使用 interface 来定义接口,需要注意的是,不要把它理解为是在定义一个对象,而要理解为 {} 括号包裹的是一个代码块,里面是一 条条声明语句,只不过声明的不是变量的值而是类型。上述代码定义的是最简单的接口结构,只有一个属性时定义成接口或许没必要,但当结构复杂时,接口的用处就会慢慢体现。

    可选属性

    当我们定义一些结构的时候,一些结构对于某些字段的要求是可选的,有这个字段就做处理,没有就忽略。接口里在属性名后面加上 ? 就可以表示这个属性是可选的:
    interface objType {
      name: string
      age?: number  // age 是可选的
    } 
    
    function func(obj: objType): void {
      let age = obj.age ? obj.age : 18
      console.log(obj.name + ' is ' + age + ' years old ')
    }

    只读属性

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

    interface Point {
      readonly x: number  // 加上readonly前缀,表示只读
      readonly y: number  // 同上 
    }
    
    let n: Point = { x: 3, y: 5 }
    
    n.x = 10  // Cannot assign to 'x' because it is a read-only property.

     定义只读变量用 const,定义只读属性用 readonly。

    额外属性检查 

    当某接口类型里不存在某个属性时,就不能应用这个属性,否则会报错,例如:

    interface Point {
      x: number
      y: number
    }
    
    let n: Point = { x: 3, y: 5, z: 10 }  // 这里加入了z属性,会报错
    
    //  Type '{ x: number; y: number; z: number; }' is not assignable to type 'Point'.
    //  Object literal may only specify known properties, and 'z' does not exist in type 'Point'.

    很多时候,我们希望绕过typescript的这个检查,那么有几个方法需要知道:

    (1)类型断言

    将值断言为Point类型,告诉typescript我们已经自行检查过了,没有问题

    let n: Point = { x: 3, y: 5, z: 10 } as Point

    (2)字符串索引签名

    定义任意属性,属性名是string类型,propName是泛指的属性名,只要不是 x 和 y,就无所谓它的值类型:

    interface Point {
      x: number
      y: number
      [propName: string]: any
    }
    
    let n: Point = { x: 3, y: 5, z: 10 }

    (3)利用类型兼容性

    这个方法说白了就是先把值赋值给一个变量,然后再把这个变量赋值给这个接口类型的变量:

    interface Point {
      x: number
      y: number
    }
    
    let obj = { x: 3, y: 5, z: 10 } // 需要的值赋值给变量
    let n: Point = obj // 变量赋值给接口类型变量

    函数类型接口

    除了描述带有属性的普通对象外,接口也可以描述函数类型。为了使用接口表示函数类型,我们需要给接口定义一个调用签名:

    interface AddFunc {
      (num1: number, num2: number): number
    }

    接口AddFunc要求实现这个接口结构的值须包含一个函数,其函数结构和接口内定义的函数结构一致。如:

    let func: AddFunc
    func = function(num1:number, num2:number): number {
      return num1 + num2
    }

    对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配。 比如,我们使用下面的代码重写上面的例子:

    let func: AddFunc
    func = function(n1:number, n2:number): number {  // n1,n2代替num1,num2
      return n1 + n2  
    }

    函数的参数会逐个进行检查,要求对应位置上的参数类型是兼容的。另外你也可以不指定类型,由typescript推导类型:

    interface AddFunc {
      (num1: number, num2: number): number
    }
    
    let func: AddFunc
    func = function(n1, n2) {
      return n1 + n2
    }

    可索引的类型接口

    接口可以描述那些“可通过索引得到”的类型,如数组 a[1] 或对象 obj["name"],可以同时给索引和值都设置类型,如:

    interface MyArray {
      [index: number]: string
    }
    
    const arr: MyArray = ['Apple', 'Orange']
    
    interface MyObject {
      [key: number]: string
    }
    
    const obj: MyObject = {
      0: 'hello',
      1: 'world'
    }

     接口的继承

    接口也可以继承,本质上就是从一个接口里复制成员到另一个接口里,更灵活的复用属性。

    // 定义一个 Person 接口,它包含两个属性和一个方法
    interface Person{
      age:number;
      name:string;
      say():void;
    }
    
    // 定义一个 Teacher 接口,继承 Person 的属性成员,同时拥有自己的 teach 方法
    interface Teacher extends Person{
      teach():void;
    }
    
    // 使用接口
    const teacher:Teacher = {
      teach(){},
      age:25,
      name:'tom',
      say(){}
    }

    混合类型

    在 js 中,函数是对象,而对象可以有属性,所以有时一个对象,它既是一个函数,也包含一些属性,如这个计数器函数:

    function countUp(){
      return ++countUp.count
    }
    countUp.count = 0
    
    console.log(countUp()) // 1
    console.log(countUp()) // 2

    现在来使用混合类型接口来定义上面 countUp 类型:

    interface Counter{
      ():void;
      count:number
    }
    
    function getCounter():Counter{
      const c = ()=>{
        c.count++
      }
      c.count = 0
      return c
    }
    
    const counter:Counter = getCounter()
    
    counter()
    console.log(counter.count)
    counter()
    console.log(counter.count)
     

    以上就是接口的相关内容,接口中还有涉及类的一些内容,后面写到类相关时再说。

  • 相关阅读:
    开源框架.netCore DncZeus学习(五)下拉树的实现
    开源框架.netCore DncZeus学习(四)项目升级
    github下载更新代码到本地
    AndroidStudio替换空行
    Ext.net获取选中行数据
    OZCode
    禁止密码显示框
    Android layout_weight理解
    微信页面关于点击按钮关注公众号放到链接里无关注按钮
    进入页面就触发了popstate事件。
  • 原文地址:https://www.cnblogs.com/wjaaron/p/11707634.html
Copyright © 2011-2022 走看看