5、TS 接口(interface)

135 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情

前几篇文章已经能覆盖大部分的使用场景, 但并不是最合适的写法。

接口 (扩展类型)

接口和类型别名一样不会出现在编译结果中。

接口:一种规范, 必要生活中的电源接口、请求后台的接口, 都需要满足某种协议才可以使用成功。

TS 中的接口:用于约束类、对象、函数的契约 (标准)。

以前开发 前后端会存在接口文档

接口文档实际上是一种弱标准: 出错的几率很大

而使用代码中的接口:几乎不存在出错的可能 (在编码的阶段就已经提示错误)

接口约束对象

语法: interface 接口名 { name:string }

约束普通属性

//定义一个约束用户的对象
interface User {
    name: string,
    age: number
}

let u: User;
//user 就必须有接口上的所有信息
u = {
    name: 'John',
    age: 30
}

就上面的例子来看, 感觉和 类型别名没有多大的区别 type User { name: string, age: number } 确实如此, 但是区别主要体现在下面 约束类(class) 上的差异。

约束函数属性

interface Fn {
    // 写法一
    sum: (a: number, b: number) => number 表示函数的返回类型 //这里不能有函数的实现
    // 写法二
    a(): number
}
let f: Fn
f = {
    sum: (a, b) => a + b
}

接口约束函数

语法:interface Sum { (a:number, b:number):number }

使用 类型别名 约束一个函数

写一个 filter 方法

type Condition = (item: number, index?: number) => boolean //类型别名

function filter(arr: number[], fn: Condition) {
    let result: number[] = []
    for (let i = 0; i < arr.length; i++) {
        if (fn(arr[i], i)) {
            result.push(arr[i])
        }
    }
    return result
}
//使用
const data = filter([1, 2, 3, 4, 5], (item) => item > 3)

使用 接口 约束一个函数

interface Condition {
    (item: number, index: number): boolean
} //接口

function filter(arr: number[], fn: Condition) {
    let result: number[] = []
    for (let i = 0; i < arr.length; i++) {
        if (fn(arr[i], i)) {
            result.push(arr[i])
        }
    }
    return result
}
//使用
const data = filter([1, 2, 3, 4, 5], (item) => item > 3)

接口的继承

继承实际上是一种逻辑含义, 比如 我是一个人, 逻辑上我有 的所有特征, 我就从逻辑上继承了 这个抽象的概念。

在 ts 中接口的继承就是 a 继承 b, 那么 a 一定有 b 的所有属性, 方法等等, 而 a 也可以有自己属性方法, 还可以覆盖继承至 b 的属性方法, 有点类似 js 的原型链。

举个栗子

//用户接口
interface User {
    name: string;
    age: number;
}
//超级用户也是用户 所以也该具有 User的属性
interface RootUSer extends User {
    root: boolean //在加上自己的特殊属性
}

// 这里 u 就一定具有 User 和 RootUser 的所有属性
let u: RootUSer = {
    name: 'John',
    age: 30,
    root: true
}

多个继承写法, 使用 **,**隔开

interface a {
    a: string
}

interface b {
    b: string
}

interface c extends a, b {
    c: string
}

const key: c = {
    a: 'a',
    b: 'b',
    c: 'c'
}

注意:

在继承的接口中, 继承者可以覆盖父类的属性但是不能改变该属性的类型

//正确使用
interface a {
    a: string
}

interface b {
    b: string
}

interface c extends a, b {
    c: string
    a: string //可以 和 a 一样
}

//错误
interface a {
    a: string
}

interface b {
    b: string
}

interface c extends a, b {
    c: string
    a: number //不可以改变其类型
}

总结

接口是一种强制协议, 更加规范了代码的书写也提升了代码的健全。