在TypeScript中的Type与Interface的区别
Type vs. Interface 是TypeScript中最令人困惑和有趣的事情之一。我们将尝试解开这种困惑。
TypeScript是建立在JavaScript之上的,它增加了静态类型。拥有类型对开发人员来说是一件很好的事情。编写类型可能很困难,但从长远来看你不会后悔。
TypeScript具有所有基本类型,如number、string、boolean等等。除了基本类型之外,TypeScript允许我们创建自定义类型,并通过类型别名和接口来定义对象的外观, 分别。
类型别名只是一种类型。使用自定义名称(别名)创建一个类型就是类型别名,仅此而已。
让我们看看接口和类型别名的基本语法。
基本语法
接口
接口将使用interface
关键字声明。请检查下面的接口语法。
interface InterfaceName {
keyName: typeOfKey
...
}
看看下面的示例。
interface Site {
name: string;
url: string;
pagesCount: number;
}
const yaoweibin: Site = {
name: 'Geekflare',
url: 'https://yaoweibin.cn/',
pagesCount: 25
}
类型别名
类型别名将使用type
关键字声明。请检查下面的类型别名语法。
type TypeName = {
keyName: typeOfKey;
...
}
看看下面的示例。
type Site = {
name: string;
url: string;
pagesCount: number
}
const yaoweibin: Site = {
name: 'Geekflare',
url: 'https://yaoweibin.cn/',
pagesCount: 25
}
我们使用接口和类型别名为Site
创建了一个类型。两者都是有效的,并且可以用于上面示例中提到的对象类型。只是上面示例中的语法不同,这是显而易见的。
让我们继续探索它们之间的区别,以找到更多的东西。
元组
TypeScript中的元组是一个有预定义长度的数组。它定义了每个索引的类型。
我们可以使用类型别名来声明元组。但我们不能使用接口来做到这一点。让我们看看如何使用类型别名。
type Site = [string, string, number]
const yaoweibin: Site = ['Geekflare', 'https://yaoweibin.cn/', 25]
在上面的示例中,我们为数组的每个索引元素定义了类型。如果我们在数组中给出其他类型,TypeScript会抛出一个错误。
我们不能用接口做到这一点吗?
我们不能像使用类型别名那样完全做到这一点。接口用于对象类型。所以,我们需要在对象内部使用元组才能在接口中使用它。让我们看一个例子。
interface Site {
details: [string, string];
pagesCount: number;
}
const yaoweibin: Site = {
details: ['Geekflare', 'https://yaoweibin.cn/'],
pagesCount: 25,
}
如果你看一下代码,我们在接口中有一个名为details的元组。因此,我们可以在接口中使用元组。
类似地,我们可以对单个类型(例如string、number、boolean等)使用类型别名。由于接口用于对象类型,我们可以将其用于单个类型,如类型别名。
另一个有趣的事情是,我们可以在接口中使用类型别名元组。请检查下面的示例。
类型细节= [string, string]
接口站点{
details:细节;
pagesCount:数字;
}
const yaoweibin:Site = {
details:[‘Geekflare','https://yaoweibin.com/'],
pagesCount:25,
}
让我们继续下一件事。
声明合并-接口
声明合并是使用TypeScript将具有相同名称的接口类型合并在一起的方法。让我们看一个例子,以便更清楚地理解。
接口网站{
名称:字符串;
}
接口网站{
url:字符串;
}
接口网站{
pagesCount:数字;
}
const极客网:网站= {
名称:'Geeflare',
url:'https://yaoweibin.com/',
pagesCount:25,
}
如果您看到上面的代码,我们已经声明了具有相同名称的接口3次。 TypeScript编译器将所有这3个表单编译为单个对象类型,其中包括具有相同名称的接口中的所有类型。
您可以通过从 yaoweibin
对象中删除一个键来确认声明合并。如果从 yaoweibin
中删除键之一,您将看到错误。
我们无法使用类型别名执行相同的操作。大多数人不使用该功能。一般而言,具有相同名称的多个接口会令人困惑。
类型别名粉丝,不要担心接口的此功能😅。
扩展
假设您声明了一个类型。现在,您想要声明另一种类型,并包括先前类型的类型。在这种情况下,我们可以扩展先前的类型。我们可以使用接口和类型别名来做到这一点。
让我们看看它们。
界面
在TypeScript中有一个名为 extends
的关键字可用于此用例。我们将使用它来扩展接口。让我们来看看例子。
接口网站{
名称:字符串;
url:字符串;
pagesCount:数字;
}
接口Geekflare扩展网站{
创始人:字符串;
}
const极客网:Geekflare = {
名称:'Geekflare',
url:'http://yaoweibin.cn/',
pagesCount:25,
创始人:'Chandan'
}
我们通过扩展 Site
接口创建了 Geekflare
接口。所有 Site
的类型都将出现在 Geeflare
接口中,并包括它们自己的类型。您可以删除 yaoweibin
变量中的 name
键以确认。
我们可以扩展多个接口,如下所示。
接口FirstHalf {
名称:字符串;
}
接口SecondHalf {
年龄:数字
}
接口人扩展FirstHalf,SecondHalf {
职业:字符串
}
const人:人= {
名称:'Geekflare',
年龄:7,
职业:'帮助技术人员'
}
尝试扩展超过2个接口以获得乐趣。我们还可以扩展类型别名与接口。
类型网站= {
名称:字符串;
url:字符串;
pagesCount:数字;
}
接口Geekflare扩展Site {
创始人:字符串;
}
const极客网:Geekflare = {
名称:'Geekflare',
url:'http://yaoweibin.cn/',
pagesCount:25,
创始人:'Chandan'
}
在上面的示例中,我们仅扩展了一个类型。您可以像上一个示例中扩展一样多次扩展。
让我们看看如何使用类型别名进行操作。
类型别名
我们可以使用TypeScript中的交集类型扩展类型别名。让我们看一个例子。
type Site = {
name: string;
url: string;
pagesCount: number;
}
type Geekflare = Site & {
founder: string;
}
const yaoweibin: Geekflare = {
name: 'Geekflare',
url: 'http://yaoweibin.cn/',
pagesCount: 25,
founder: 'Chandan'
}
我们使用交集(&)将Site
类型扩展为Geekflare
类型,并为其添加了founder
属性。您可以通过从yaoweibin
变量中删除一个键来测试它,这将导致错误。
与接口类似,我们可以按以下方式扩展多个类型。
type FirstHalf = {
name: string;
}
type SecondHalf = {
age: number
}
type Person = FirstHalf & SecondHalf & {
profession: string
}
const person: Person = {
name: 'Geekflare',
age: 7,
profession: 'Helping Techies'
}
我们还可以像接口扩展类型别名一样扩展接口。请查看下面的示例。
interface Site {
name: string;
url: string;
pagesCount: number;
}
type Geekflare = Site & {
founder: string;
}
const yaoweibin: Geekflare = {
name: 'Geekflare',
url: 'http://yaoweibin.cn/',
pagesCount: 25,
founder: 'Chandan'
}
尝试扩展类型别名和接口的组合。
实现
这不是接口和类型别名之间的区别,只是了解class的一个特性。
一个类可以以相同的方式实现接口和类型别名。让我们分别看一下它们的示例。
接口
interface Site {
name: string;
url: string;
pagesCount: number;
}
class Geekflare implements Site {
name = 'Geekflare'
url = 'http://yaoweibin.cn/'
pagesCount = 25
constructor() {
console.log(this.name, this.url, this.pagesCount)
}
}
类型别名
type Site = {
name: string;
url: string;
pagesCount: number;
}
class Geekflare implements Site {
name = 'Geekflare'
url = 'http://yaoweibin.cn/'
pagesCount = 25
constructor() {
console.log(this.name, this.url, this.pagesCount)
}
}
注意:需要记住的一件事是,我们不能使用类实现联合(|)或交集(&)类型。
最后的话
正如你在文章中所看到的,我们可以使用类型别名和接口来完成所有操作。因此,我们不能严格说一个比另一个更好。最终,选择哪个取决于个人的选择。您将逐渐发展出自己使用它们的风格。
接下来,您可以查看Typescript vs. Javascript。
Happy Coding 🙂