目录:
- 本章将认识到 interface 是什么?
- interface 的特点
- interface 常用的三种操作
- interface/type 的区别
什么是接口?
接口用于对行为的抽象, 一般用于描述一个数据结构的组成方式
interface/type 如何选择
interface 一般用于定义有具体结构的, 比如 对象, 类, 混合类型(函数就是一个混合对象)
interface IPerson {
name: string;
age: number;
}
const person: IPerson = {
name: 'Xiao',
age: 20
}
type 一般用于定义 函数
type ISum = (x: number, b: number) => number;
const sum: ISum = (a, b) => {
return a + b;
}
总结:
interface 用于描述结构居多
type 用于对 函数签名 的描述
interface 的特点
重名合并特性
interface 重名是可以合并 并不会抛出错误
interface IPerson {
name: string;
age: number;
}
interface IPerson {
gender: 'male' | 'female';
industry: string;
}
class Person implements IPerson {
constructor(
public name: IPerson['name'],
public age: IPerson['age'],
public gender: IPerson['gender'],
public industry: IPerson['industry'],
) {}
}
const person: IPerson = {
name: "",
age: 0,
gender: "male",
industry: ""
}
继承
interface 可以使用 extends 继承 接口或类 加以扩展
注意点:
- 当类继承了 接口必选属性必须实现
- 当接口继承类, 仅仅只会继承对结构的描述
interface IAnimal {
name: string;
age: number;
type: string;
}
interface ICat extends IAnimal {
type: 'white' | 'black'; // 黑或白猫
eat: 'meat';
size?: number; // 可选类型
}
class Cat implements ICat {
constructor(
public name: ICat['name'],
public age: ICat['age'],
public type: ICat['type'],
public eat: ICat['eat'],
public size?: ICat['size'],
) {}
}
接口继承类 仅继承了对类的描述 结构, 比如 方法, 属性
class Animal {
public name!: string;
public age!: number;
public type!: string;
eat() {
console.log('eating food');
}
}
interface IAnimal extends Animal {
// 定义原型方法
run(): void;
// 可选方法
foods?() :void;
}
class Cat implements IAnimal {
public name!: string;
public age!: number;
public type!: string;
run(): void {
throw new Error("Method not implemented.");
}
eat(): void {
throw new Error("Method not implemented.");
}
}
interface 不可使用 遍历 与 条件判断
// 无法使用 extends 进行 条件判断
interface IPerson<T extends object> {
[K in keyof T]: T[K] extends object ? 1 : 0; // error
}
type IPerson1<T extends object> = {
[K in keyof T]: T[K] extends object ? 1 : 0;
}
// 无法使用 in 进行遍历
interface IPerson<T extends object> {
[K in keyof T]: T[K] // error
}
type IPerson1<T extends object> = {
[K in keyof T]: T[K]
}
interface 不可进行 联合 或 交叉
interface IPerson = {
name: string;
} & {
age: number;
}
interface IPerson1 = {
name: string;
} | {
age: number;
}
type IPerson2 = {
name: string;
} & {
age: number;
}
type IPerson3 = {
name: string;
} | {
age: number;
}
interface 常用的四种操作
- 添加 可选属性
interface IPerson {
name: string;
age: number;
address?: object; // 可选参数
}
- 添加 只读属性
interface IPerson {
name: string;
age: number;
readonly address: object;
}
- 添加 任意属性扩展
interface IPerson {
// 定义键位 string, 值为任意类型
[K: string]: any;
}
const person: IPerson = {};
person.name = 'Xiao';
person.age = 19;
- 索引访问符
interface IPerson {
name: string;
age: number;
address: {
home: string;
address: string
}
}
type IAddress = IPerson['address'];
type IAddressHome = keyof IPerson['address']; // type IAddressHome = "address" | "home"
总结 interface 与 type 区别
- 语法: type 可用 判断与循环, interface 不可用
- 重名: 重名合并(扩展)
- 扩展: 继承
- 复杂类型: type 可以使用联合交叉类型
- 使用上: interface 一般用于 类/对象, type 一般用于 函数