TypeScript 中的类型与接口

已发表: 2022-11-02

Type vs. Interface是 TypeScript 中最令人困惑和有趣的事情之一。 我们将努力消除这种混乱。

TypeScript 是在 JavaScript 之上创建的,它添加了静态类型。 拥有类型对开发人员来说是一件美妙的事情。 写类型会很困难,但从长远来看你不会后悔的。

TypeScript 具有所有基本类型,例如数字、字符串、布尔值等。除了基本类型,TypeScript 还允许我们创建自定义类型并在类型别名和接口的帮助下定义对象的外观, 分别。

类型别名不过是类型。 创建具有自定义名称(别名)的类型使其成为类型别名,仅此而已。

让我们看一下InterfacesType Aliases的基本语法。

基本语法

接口

接口将使用interface关键字声明。 检查以下接口的语法。

 interface InterfaceName { keyName: typeOfKey ... }

看看下面的示例。

 interface Site { name: string; url: string; pagesCount: number; } const geekflare: Site = { name: 'Geekflare', url: 'https://geekflare.com/', pagesCount: 25 }

类型别名

类型别名将使用type关键字声明。 检查下面类型别名的语法。

 type TypeName = { keyName: typeOfKey; ... }

看看下面的示例。

 type Site = { name: string; url: string; pagesCount: number } const geekflare: Site = { name: 'Geekflare', url: 'https://geekflare.com/', pagesCount: 25 }

我们使用接口类型别名Site创建了一个类型。 两者都是有效的,可用于示例中提到的对象类型。 上面的例子只有语法不同,这是显而易见的。

让我们继续探索它们之间的差异以找到更多的东西。

元组

TypeScript 中的元组是一个类型化的预定义长度数组。 它定义了每个索引的类型。

我们可以使用类型别名来声明元组。 但是我们不能使用接口来做到这一点。 让我们看看如何使用类型别名来做到这一点。

 type Site = [string, string, number] const geekflare: Site = ['Geekflare', 'https://geekflare.com/', 25]

在上面的示例中,我们为数组的每个索引元素定义了类型。 如果我们在数组中给出其他类型,TypeScript 会抛出错误。

我们不能用接口来做吗?

我们不能完全像使用类型别名那样做。 接口用于对象类型。 因此,我们需要在对象内部拥有元组才能在接口中使用它。 让我们看一个例子。

 interface Site { details: [string, string]; pagesCount: number; } const geekflare: Site = { details: ['Geekflare', 'https://geekflare.com/'], pagesCount: 25, }

如果你看到代码,我们在接口中有一个名为details的元组。 因此,我们可以使用接口内部的元组。

同样,我们可以为字符串、数字、布尔值等单一类型使用类型别名。由于接口用于对象类型,我们可以将其用于类型别名等单一类型。

另一个有趣的事情是我们可以在接口中使用类型别名元组。 检查以下示例。

 type Details = [string, string] interface Site { details: Details; pagesCount: number; } const geekflare: Site = { details: ['Geekflare', 'https://geekflare.com/'], pagesCount: 25, }

让我们继续下一件事。

声明合并——接口

声明合并是使用 TypeScript 合并具有相同名称的接口类型。 让我们看一下示例以更清楚地了解它。

 interface Site { name: string; } interface Site { url: string; } interface Site { pagesCount: number; } const geekflare: Site = { name: 'Geeflare', url: 'https://geekflare.com/', pagesCount: 25, }

如果你看到上面的代码,我们已经声明了 3 次同名的接口。 TypeScript 编译器会将所有这 3 种形式编译成一个对象类型,其中包括来自具有相同名称的接口的所有类型。

您可以通过从geekflare对象中删除一个键来确认声明合并。 如果您从geekflare中删除其中一个键,您将看到一个错误。

我们不能对类型别名做同样的事情。 大多数人不使用该功能。 一般来说,拥有多个同名的接口是令人困惑的。

输入别名粉丝,不用担心接口的这个特性。

扩展

假设您已经声明了一个类型。 现在,您想要声明另一个类型以及前一个类型的类型。 在这种情况下,我们可以扩展以前的类型。 我们可以使用接口类型别名来做到这一点。

让我们看看他们俩。

接口

在 TypeScript 中有一个用于此用例的关键字extends 。 我们将使用它来扩展接口。 让我们检查一下这个例子。

 interface Site { name: string; url: string; pagesCount: number; } interface Geekflare extends Site { founder: string; } const geekflare: Geekflare = { name: 'Geekflare', url: 'http://geekflare.com/', pagesCount: 25, founder: 'Chandan' }

我们通过扩展Site接口创建了Geekflare接口。 Geeflare界面中将显示所有类型的Site以及它们自己的类型。 您可以从geekflare变量中删除name键以确认它。

我们可以如下扩展多个接口。

 interface FirstHalf { name: string; } interface SecondHalf { age: number } interface Person extends FirstHalf, SecondHalf { profession: string } const person: Person = { name: 'Geekflare', age: 7, profession: 'Helping Techies' }

尝试使用超过 2 个接口进行扩展以获得乐趣。 我们还可以使用接口扩展类型别名

 type Site = { name: string; url: string; pagesCount: number; } interface Geekflare extends Site { founder: string; } const geekflare: Geekflare = { name: 'Geekflare', url: 'http://geekflare.com/', pagesCount: 25, founder: 'Chandan' }

在上面的例子中,我们只扩展了一种类型。 您可以根据需要扩展任意数量,类似于前面扩展多个接口的示例。

让我们看看如何使用类型别名来做到这一点。

类型别名

我们可以使用 TypeScript 中的交集类型来扩展类型别名。 让我们看一个例子。

 type Site = { name: string; url: string; pagesCount: number; } type Geekflare = Site & { founder: string; } const geekflare: Geekflare = { name: 'Geekflare', url: 'http://geekflare.com/', pagesCount: 25, founder: 'Chandan' }

我们使用交集 (&) Geekflare founder扩展了Site类型。 您可以通过从geekflare变量中删除其中一个键来测试它,这将引发错误。

与接口类似,我们可以扩展多种类型,如下所示。

 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 geekflare: Geekflare = { name: 'Geekflare', url: 'http://geekflare.com/', pagesCount: 25, founder: 'Chandan' }

尝试扩展类型别名和接口的组合。

实施

这不是接口和类型别名之间的区别。 只是class的一个特性要知道。

一个类可以以相同的方式实现接口和类型别名。 让我们看看他们两个的例子。

接口

interface Site { name: string; url: string; pagesCount: number; } class Geekflare implements Site { name = 'Geekflare' url = 'http://geekflare.com/' 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://geekflare.com/' pagesCount = 25 constructor() { console.log(this.name, this.url, this.pagesCount) } }

注意:要记住的一件事是我们不能用类实现联合 (|)交集 (&)类型。

最后的话

正如您在文章中看到的那样,我们可以使用类型别名和接口来做任何事情。 所以,我们不能严格地说一个比另一个好。 最后,选择其中之一是个人的选择。 你最终会发展出你使用它们的风格。

接下来,您可以查看 Typescript 与 Javascript。

快乐编码