前言
接口是我们在进行模块、方法等的封装时经常会用到的一个概念,使用接口可以:
- 将一类具体事务抽象成单一的对象方法,使用者不必关心内部的实现逻辑,只需要按照要求传入对应的参数即可得到预期的结果输出,从很大程度上减轻了使用者的心智负担。
- 一处定义,多处使用,减轻后续的维护负担。
TypeScript 也有接口的概念,它被用来校验数据类型是否符合要求。
TypeScript 接口就像是一份具有名称的契约或者规则,契约的内容规定了某个数据结构里面的数据组成和类型,只要有某处通过名称调用了这份契约,那就意味着此处的数据必须要接受并通过契约内容的检查,否则会报错。
JavaScript 代码示例
如果用 JavaScript,我们的代码可能是这样的:
function printInfo(info){
console.log(info.name);
}
printInfo({name: "编程三昧"});
// 编程三昧
printInfo({age: 22});
// undefined
printInfo();
// Uncaught TypeError: Cannot read properties of undefined (reading 'name')
由于 JavaScript 没有静态类型检查机制,在代码真正运行前无法准确判断可能会出现的问题。经常在调用一个接口前,还需要研究一下这个接口相关的源码,这很不利于协同开发。
我们迫切需要一种能够在方法调用时明确显示所需参数类型及格式的机制。
不使用接口的 TypeScript 代码示例
在学习 TypeScript 接口之前,我们的 TypeScript 代码可能是这样的:
let personalInfo_1: { name: string; age: number } = {
name: "编程三昧",
age: 22
};
let personalInfo_2: { name: string; age: number } = {
name: "隐逸王",
age: 22
};
虽然达到了数据类型检查的目的,但是很明显,类型检查器 { name: string; age: number }
重复,造成了代码冗余。
为什么要用 TypeScript 接口?
上面两段代码暴露出两个问题:
- 没有类型检查器的机制不利于协同开发;
- 常规的 TypeScript 类型检查器写法容易造成代码冗余。
使用 TypeScript 接口就可以解决上述问题。比如:
interface PersonalInfo {
name: string;
age: number;
}
function printPersonalInfo(info: PersonalInfo): void {
console.log(info);
}
let personalInfo_1: PersonalInfo = {
name: "编程三昧",
age: 22
};
let personalInfo_2 = {
name: "隐逸王",
age: 22,
gender: "Male"
}
let personalInfo_3 = {
age: 22
}
printPersonalInfo(personalInfo_1);
// 编程三昧
printPersonalInfo(personalInfo_2);
// 隐逸王
printPersonalInfo(personalInfo_3);
// Error,具体报错信息如下图
可以看到,通过使用 TypeScript 接口,既实现了类型检查,又减少了重复指定类型检查器的冗余。
就像我们之前说的,TypeScript 接口就是一份约束数据类型的契约,谁都可以通过名称去使用它来约束自己的数据类型,这就实现了复用的效果。
存在的疑惑
在上面代码中,不知道大家有没有注意到一点比较怪异的地方:personalInfo_2 的数据类型并不符合 printPersonalInfo 方法中指定的数据类型,但是代码却没有报错。
关于这一点,不知道大家都是怎么理解的?
总结
本文主要介绍了为什么要用 TypeScript 接口的原因以及用接口的好处。接口就像是一份契约,内容规定了数据格式,任何变量都可通过接口名称使用接口进行类型检查。
并且还引出了一个疑惑点,大家可以就这个问题给出自己的见解,欢迎在评论区交流!
~
~ 本文完,感谢阅读!
~
学习有趣的知识,结识有趣的朋友,塑造有趣的灵魂!