作为 JavaScript 的超集,TypeScript 引入了强大的静态类型检查功能,使得我们可以在运行程序前就找到并更正一些潜在的问题。TypeScript 还支持定义和使用类与泛型,这也让开发变得更加容易。在这篇文章中,我们希望能对 TypeScript 类与泛型的使用进行一定的探索。
类与对象
在许多编程语言中,类和对象的概念都不会令人感到陌生。一个类描述了一种可能较为复杂的数据类型,并附带了对这种数据类型进行操作的方法。对象则是类的一个实例,拥有具体的数据,可以实际进行操作。
在 TypeScript 中,可以这样创建一个类:
class Something {
note:string;
constructor(record:note) {
this.note = note
}
getNote():void {
console.log(this.note)
}
setNote(record):void {
this.note = note
}
}
这个名为 Something 的类具有一个 string 类型的数据成员,名为 note,还有可以操作该数据成员的成员函数 getNote() 与 setNote(),以及一个构造函数。
泛型
泛型提供了“类型变量”的功能,这使得开发者可以在定义类型时引入变量,并在合适的地方使用该变量,且仍然保持严谨的类型检查。这与直接放弃类型检查不同,虽然不检查类型的确能够允许用户在调用函数时传入任何信息,但是这样依赖函数的返回值也将是任意的。在参数与返回值需要对应的场景,这显然不大合适。
假设在上方 Something 类存在的同时还有个类叫 AnotherThing,其 note 成员需要在构造时提供,且不能再修改。
class AnotherThing {
note:string;
constructor(record:note) {
this.note = note
}
}
如果能有一个函数,能够实现同时获取这两种类的对象中的 note 并返回对象本身就好了。此时,就是泛型大展身手的时候了。泛型在这里约定了一个类型变量 T,要求参数 arg 传入的类型是 T ,最后返回的类型也仍然是 T。为了确保 T 类型具有 note 成员,我们还定义了 HasNote 接口,要求 T 类型一定要有 note 成员。因此,有了下方这段代码:
interface HasNote {
note: string;
}
function findRecord<T extends HasRecord>(arg: T): T {
console.log(arg.record);
return arg;
}
至此,我们对 TypeScript 类与泛型的使用应该有了一定的了解。我们可以在合适的地方运用这些特性,结合 TypeScript 的静态类型检查等功能,构建更容易维护的 JavaScript 程序。