一、概述

TypeScript 的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做 “鸭式辨型法” 或 “结构性子类型化”。 在 TypeScrip t里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。

二、什么是接口?

在面向对象语言中,接口(Interfaces)是一个很重要的概念,它是对行为的抽象,而具体如何行动需要由类(classes)去实现(implement)。TypeScript 中的接口是一个非常灵活的概念,除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述。

三、简单例子

  1. // -- 定义接口,使用 interface 关键字
  2. interface IPerson {
  3. /** 定义属性 */
  4. readonly id: number; // 只读属性,不允许被修改
  5. name: string; // 必选属性
  6. age?: number; // 可选属性
  7. [prop: string]: unknown; // 任意属性(无意义)
  8. /** 定义方法 */
  9. play: (k: string) => void;
  10. }

四、接口继承

// -- 定义一个 ITeacher 的接口 继承 IPerson
interface ITeacher extends IPerson {
    teach: (course: string) => void;
}

五、类实现接口

// -- 定义 Teacher 类实现 ITeacher 接口
class Teacher implements ITeacher {
    readonly id = 1;
    name = 'Li-HONGYAO';
    major =  "";
    play(k: string) {}
    teach(course: string) {}
}

const teacher = new Teacher();
teacher.id = 123; // Cannot assign to 'id' because it is a read-only property.
console.log(teacher.id); // 1

六、补充

接口除了被类实现以外,也可以作为类型存在,用于约束某个变量的形状,比如:

// -- 定义描述经纬度的形状
interface Coordinate {
    lat: number;
    lng: number;
}

let x: Coordinate = {
    lat: 0,
    lng: 0
}

可以看到,在这里 interfacetype 的功能非常类似,那二者有什么异同点呢?

@相同点

1)都可以描述一个对象或者函数;

2)都允许扩展( extends ),只是语法不同;

我们重点介绍第2点,interface 可以通过 extends 关键字(其实就是继承)实现扩展,而 type 则是通过 交叉类型( **&** 实现的。来看示例:

// -- interface extends interface
interface A {
    name: string;
}
interface B extends A {
    age: string;
}

// -- interface extends type 
type A = { name: string; }
interface B extends A {
    age: string;
}

// -- type extends type 
type A = { name: string; }
type B = A & { age: number; }

// -- type extends interface 
interface A {
    name: string;
}
type B = A & { age: number; }

@不同点

1)type 可以声明基本类型别名,联合类型,元祖等类型

2)type 语句中还可以使用 typeof 获取实例的类型进行赋值,比如:

var o = {
    name:'Li-HONGYAO',
    age: 18,
    major: '前端工程师'
};
type UsrType = typeof o;

/*
type UsrType = {
    name: string;
    age: number;
    major: string;
}*/

3)type 语句中还可以使用 keyof 获取实例的 key 作为联合类型进行赋值,比如:

var o = {
    name:'Li-HONGYAO',
    age: 18,
    major: '前端工程师'
};
type UsrType = keyof (typeof o);

/*
type UsrType = "name" | "age" | "major" 
*/