范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

如何在TypeScript中使用接口

  介绍
  TypeScript 是 JavaScript 语言的扩展,它使用 JavaScript 运行时和编译时类型检查器。
  TypeScript 提供了多种方法来表示代码中的对象,其中一种是使用接口。TypeScript 中的接口有两种使用场景:您可以创建类必须遵循的约定,例如,这些类必须实现的成员,还可以在应用程序中表示类型,就像普通的类型声明一样。
  您可能会注意到接口和类型共享一组相似的功能。
  事实上,一个几乎总是可以替代另一个。
  主要区别在于接口可能对同一个接口有多个声明,TypeScript 将合并这些声明,而类型只能声明一次。您还可以使用类型来创建原始类型(例如字符串和布尔值)的别名,这是接口无法做到的。
  TypeScript 中的接口是表示类型结构的强大方法。它们允许您以类型安全的方式使用这些结构并同时记录它们,从而直接改善开发人员体验。
  在今天的文章中,我们将在 TypeScript 中创建接口,学习如何使用它们,并了解普通类型和接口之间的区别。
  我们将尝试不同的代码示例,可以在 TypeScript 环境或 TypeScript Playground(一个允许您直接在浏览器中编写 TypeScript 的在线环境)中遵循这些示例。准备工作
  要完成今天的示例,我们将需要做如下准备工作:一个环境。我们可以执行 TypeScript 程序以跟随示例。要在本地计算机上进行设置,我们将需要准备以下内容。 为了运行处理 TypeScript 相关包的开发环境,同时安装了 Node 和 npm(或 yarn)。本文教程中使用 Node.js 版本 为14.3.0 和 npm 版本 6.14.5 进行了测试。要在 macOS 或 Ubuntu 18.04 上安装,请按照如何在 macOS 上安装 Node.js 和创建本地开发环境或如何在 Ubuntu 18.04 上安装 Node.js 的使用 PPA 安装部分中的步骤进行操作。如果您使用的是适用于 Linux 的 Windows 子系统 (WSL),这也适用。 此外,我们需要在机器上安装 TypeScript 编译器 (tsc)。为此,请参阅官方 TypeScript 网站。 如果你不想在本地机器上创建 TypeScript 环境,你可以使用官方的 TypeScript Playground 来跟随。 您将需要足够的 JavaScript 知识,尤其是 ES6+ 语法,例如解构、rest 运算符和导入/导出。如果您需要有关这些主题的更多信息,建议阅读我们的如何用 JavaScript 编写代码系列。 本文教程将参考支持 TypeScript 并显示内联错误的文本编辑器的各个方面。这不是使用 TypeScript 所必需的,但确实可以更多地利用 TypeScript 功能。为了获得这些好处,您可以使用像 Visual Studio Code 这样的文本编辑器,它完全支持开箱即用的 TypeScript。你也可以在 TypeScript Playground 中尝试这些好处。
  本教程中显示的所有示例都是使用 TypeScript 4.2.2 版创建的。在 TypeScript 中创建和使用接口
  在本节中,我们将使用 TypeScript 中可用的不同功能创建接口,您还将学习如何使用您创建的接口。
  TypeScript 中的接口是通过使用 interface 关键字后跟接口名称,然后是带有接口主体的 {} 块来创建的。例如,这里是一个 Logger 接口:interface Logger {   log: (message: string) => void; }
  与使用类型声明创建普通类型类似,我们可以在 {} 中指定类型的字段及其类型:interface Logger {   log: (message: string) => void; }
  Logger 接口表示一个对象,该对象具有一个名为 log 的属性。此属性是一个接受字符串类型的单个参数并返回 void 的函数。
  我们可以将 Logger 接口用作任何其他类型。下面是一个创建与 Logger 接口匹配的对象字面量的示例:interface Logger {   log: (message: string) => void; } const logger: Logger = {   log: (message) => console.log(message), };
  使用 Logger 接口作为其类型的值必须具有与 Logger 接口声明中指定的成员相同的成员。如果某些成员是可选的,则可以省略它们。
  由于值必须遵循接口中声明的内容,因此,添加无关字段将导致编译错误。例如,在对象字面量中,尝试添加接口中缺少的新属性:interface Logger {   log: (message: string) => void; } const logger: Logger = {   log: (message) => console.log(message),   otherProp: true, };
  在这种情况下,TypeScript 编译器会发出错误 2322,因为 Logger 接口声明中不存在此属性:Output Type "{ log: (message: string) => void; otherProp: boolean; }" is not assignable to type "Logger".   Object literal may only specify known properties, and "otherProp" does not exist in type "Logger". (2322)
  与使用普通类型声明类似,可以通过附加 ? 将属性转换为可选属性。以他们的名义。扩展其他类型
  创建接口时,我们可以从不同的对象类型进行扩展,允许您的接口包含来自扩展类型的所有类型信息。这使您能够编写具有一组通用字段的小型接口,并将它们用作构建块来创建新接口。
  想象一下,我们如果有一个 Clearable 接口,比如这个:interface Clearable {   clear: () => void; }
  然后,我们可以创建一个从它扩展的新接口,继承它的所有字段。在以下示例中,接口 Logger 是从 Clearable 接口扩展而来的。注意突出显示的行:interface Clearable {   clear: () => void; }  interface Loggerextends Clearable{   log: (message: string) => void; }
  Logger 接口现在还有一个 clear 成员,它是一个不接受参数并返回 void 的函数。这个新成员继承自 Clearable 接口。就像我们这样做一样:interface Logger {   log: (message: string) => void;   clear: () => void; }
  当使用一组通用字段编写大量接口时,我们可以将它们提取到不同的接口并更改接口以扩展创建的新接口。
  回到前面使用的 Clearable 示例,假设我们的应用程序需要一个不同的接口,例如下面的 StringList 接口,来表示一个包含多个字符串的数据结构:interface StringList {   push: (value: string) => void;   get: () => string[]; }
  通过使这个新的 StringList 接口扩展现有的 Clearable 接口,指定该接口还具有在 Clearable 接口中设置的成员,将 clear 属性添加到 StringList 接口的类型定义中:
  interface StringList extends Clearable {   push: (value: string) => void;   get: () => string[]; }
  接口可以从任何对象类型扩展,例如接口、普通类型,甚至是类。带有可调用签名的接口
  如果接口也是可调用的(也就是说,它也是一个函数),我们可以通过创建可调用签名在接口声明中传达该信息。
  通过在未绑定到任何成员的接口内添加函数声明并在设置函数的返回类型时使用 : 而不是 => 来创建可调用签名。
  例如,在 Logger 界面中添加一个可调用的签名,如下面突出显示的代码所示:interface Logger {   (message: string): void;   log: (message: string) => void; }
  请注意,可调用签名类似于匿名函数的类型声明,但在返回类型中,我们使用的是 : 而不是 =>。这意味着绑定到 Logger 接口类型的任何值都可以作为函数直接调用。
  要创建与Logger 接口匹配的值,我们需要考虑接口的要求:它必须是可调用的。 它必须有一个名为 log 的属性,该属性是一个接受单个字符串参数的函数。
  让我们创建一个名为 logger 的变量,它可以分配给 Logger 接口的类型:
  interface Logger {   (message: string): void;   log: (message: string) => void; } const logger: Logger = (message: string) => {   console.log(message); } logger.log = (message: string) => {   console.log(message); }
  要匹配 Logger 接口,该值必须是可调用的,这就是我们将 logger 变量分配给函数的原因:interface Logger {   (message: string): void;   log: (message: string) => void; } const logger: Logger = (message: string) => { console.log(message); } logger.log = (message: string) => {   console.log(message); }
  然后,我们将 log 属性添加到 logger 函数:interface Logger {   (message: string): void;   log: (message: string) => void; } const logger: Logger = (message: string) => {   console.log(message); } logger.log = (message: string) => { console.log(message); }
  这是 Logger 接口所要求的。绑定到 Logger 接口的值还必须具有 log 属性,该属性是一个接受单个字符串参数并返回 void 的函数。
  如果我们没有包含 log 属性,TypeScript Compiler 会给你错误 2741:Output Property "log" is missing in type "(message: string) => void" but required in type "Logger". (2741)
  如果 logger 变量中的 log 属性具有不兼容的类型签名,TypeScript 编译器将发出类似的错误,例如将其设置为 true:
  interface Logger {   (message: string): void;   log: (message: string) => void; } const logger: Logger = (message: string) => {   console.log(message); } logger.log = true;
  在这种情况下,TypeScript 编译器会显示错误 2322:
  Output Type "boolean" is not assignable to type "(message: string) => void". (2322)
  将变量设置为具有特定类型的一个很好的功能,在这种情况下,将记录器变量设置为具有记录器接口的类型,TypeScript 现在可以推断记录器函数和日志中函数的参数类型 财产。
  我们可以通过从两个函数的参数中删除类型信息来检查。请注意,在下面突出显示的代码中,消息参数没有类型:interface Logger {   (message: string): void;   log: (message: string) => void; } const logger: Logger = (message)=> {   console.log(message); } logger.log = (message)=> {   console.log(message); }
  在这两种情况下,编辑器应该仍然能够显示参数的类型是字符串,因为这是 Logger 接口所期望的类型。带有索引签名的接口
  可以向界面添加索引签名,就像使用普通类型一样,从而允许界面具有无限数量的属性。
  例如,如果想创建一个具有无限数量的字符串字段的 DataRecord 接口,可以使用以下突出显示的索引签名:interface DataRecord {   [key: string]: string; }
  然后,我们可以使用 DataRecord 接口设置具有多个字符串类型参数的任何对象的类型:interface DataRecord {   [key: string]: string; } const data: DataRecord = {   fieldA: "valueA",   fieldB: "valueB",   fieldC: "valueC",   // ... };
  在本文中,我们使用 TypeScript 中可用的不同功能创建了接口,并学习了如何使用您创建的接口。
  在接下来的内容中,我们将了解更多关于类型和接口声明之间的区别,并获得声明合并和模块扩充的实践。类型和接口的区别
  到目前为止,我们已经看到接口声明和类型声明是相似的,具有几乎相同的特性集。
  例如,我们创建了一个从 Clearable 接口扩展而来的 Logger 接口:interface Clearable {   clear: () => void; } interface Logger extends Clearable {   log: (message: string) => void; }
  可以使用两种类型声明来复制相同的类型表示:type Clearable = {   clear: () => void; } type Logger = Clearable & {   log: (message: string) => void; }
  如前面内容所示,接口声明可用于表示各种对象,从函数到具有无限数量属性的复杂对象。这也适用于类型声明,甚至从其他类型扩展,因为,我们可以使用交集运算符 & 将多个类型相交。
  由于类型声明和接口声明非常相似,因此,需要考虑各自独有的特定功能,并在代码库中保持一致。选择一种在代码库中创建类型表示,并且仅在需要仅对它可用的特定功能时才使用另一种。
  例如,类型声明具有接口声明所缺乏的一些特性,例如:联合类型。 映射类型。 原始类型的别名。
  仅可用于接口声明的功能之一是声明合并,我们将在接下来的内容中学习它。重要的是要注意,如果您正在编写一个库并希望为库用户提供扩展库提供的类型的能力,那么声明合并可能很有用,因为类型声明无法做到这一点。声明合并
  TypeScript 可以将多个声明合并为一个声明,使他们能够为同一个数据结构编写多个声明,并在编译期间将它们捆绑在一起,就像它们是一个单一类型一样。
  在文中,我们将看到它是如何工作的,以及为什么它在使用接口时很有帮助。
  TypeScript 中的接口可以重新打开;也就是说,可以合并同一接口的多个声明。当我们想要将新字段添加到现有界面时,这很有用。
  例如,假设我们有一个名为 Databaseoptions 的接口,如下所示:interface DatabaseOptions {   host: string;   port: number;   user: string;   password: string; }
  此接口将用于在连接到数据库时传递选项。
  稍后在代码中,声明一个具有相同名称但具有一个名为 dsnUrl 的字符串字段的接口,如下所示interface DatabaseOptions {   dsnUrl: string; }
  当 TypeScript 编译器开始读取我们的代码时,它会将 DatabaseOptions 接口的所有声明合并为一个。从 TypeScript 编译器的角度来看,DatabaseOptions 现在是:interface DatabaseOptions {   host: string;   port: number;   user: string;   password: string;   dsnUrl: string; }
  该接口包括我们最初声明的所有字段,以及我们单独声明的新字段 dsnUrl。两个声明已合并。模块扩充
  当我们需要使用新属性扩充现有模块时,声明合并很有帮助。一个用例是,当我们向库提供的数据结构添加更多字段时。这在名为 express 的 Node.js 库中相对常见,它允许我们创建 HTTP 服务器。
  使用 express 时,一个 Request 和一个 Response 对象被传递给我们的请求处理程序(负责为 HTTP 请求提供响应的函数)。Request 对象通常用于存储特定于特定请求的数据。例如,我们可以使用它来存储发出初始 HTTP 请求的登录用户:const myRoute = (req: Request, res: Response) => {   res.json({ user: req.user}); }
  在这里,请求处理程序将用户字段设置为登录用户的 json 发送回客户端。使用负责用户身份验证的快速中间件,将登录的用户添加到代码中另一个位置的请求对象。
  Request 接口本身的类型定义没有用户字段,因此上面的代码会给出类型错误 2339:Property "user" does not exist on type "Request". (2339)
  要解决这个问题,我们必须为 express 包创建一个模块扩充,利用声明合并向请求接口添加一个新属性。
  如果我们在 express 类型声明中检查 Request 对象的类型,我们会注意到它是一个添加在名为 Express 的全局命名空间中的接口,如 DefinitiveTyped 存储库中的文档所示:declare global {     namespace Express {         // These open interfaces may be extended in an application-specific manner via declaration merging.         // See for example method-override.d.ts (https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/method-override/index.d.ts)         interface Request {}         interface Response {}         interface Application {}     } }
  注意:类型声明文件是只包含类型信息的文件。DefinitiveTyped 存储库是为没有类型声明的包提交类型声明的官方存储库。npm 上可用的 @types/ 包是从此存储库发布的。
  要使用模块扩充向 Request 接口添加新属性,我们必须在本地类型声明文件中复制相同的结构。例如,假设我们创建了一个名为 express.d.ts 的文件,如下所示,然后将其添加到 tsconfig.json 的 types 选项中:import "express"; declare global {   namespace Express {     interface Request {       user: {         name: string;       }     }   } }
  从 TypeScript 编译器的角度来看,Request 接口有一个用户属性,它们的类型设置为一个对象,该对象具有一个称为字符串类型名称的属性。发生这种情况是因为同一接口的所有声明都被合并了。
  假设我们正在创建一个库,并希望为我们的库的用户提供增加自己的库提供的类型的选项,就像我们在上面使用 express 所做的那样。在这种情况下,我们需要从库中导出接口,因为普通类型声明不支持模块扩充。结论
  到这里,在本文提供的教程就结束了。
  我们编写了多个 TypeScript 接口来表示各种数据结构,发现了如何将不同的接口一起用作构建块来创建强大的类型,并了解了普通类型声明和接口之间的区别。
  我们现在可以开始为代码库中的数据结构编写接口,让我们拥有类型安全的代码和文档。

2021笔记本选购指南完整版推荐快来看看你适合哪款掌握一些基础的笔记本电脑知识,无论是自己购买,还是给亲戚朋友,或者上大学的亲戚进行推荐(有部分专业对于笔记本电脑要求很高),都可以做到有的放矢,也不用到处去搜索笔记本电脑选购攻略,那些被低估的4G手机,你知道多少?虽然现在是5G时代,但是又很多4G手机,还是非常划算的。如红米K30,搭载了骁龙730G处理器,日常运行都很流畅。屏幕上,采用了120HZ的刷新率,要知道小米10系列才90HZ。续摩托罗拉G505G手机海外发布联发科天玑700芯片加持早在2021年4月份的时候,联想旗下的摩托罗拉手机,在国内智能手机市场发布了MotoG50手机。按照介绍,这款智能手机采用6。5英寸的MaxVisionHD屏,该屏幕的分辨率为16aigo六位延长线插座(18W快充版)评测用了多个插座后才选对随着电子产品的增多,家庭生活越来越离不开插座。虽说插座很常见,不过我估计很多人都不会选择,因为我也是从吃亏中一步步走过来的。为了让大家少走弯路,今天我给大家带来一款aigo六位延长华为和苹果真的天差地别吗?手机跟汽车一样,都是一国科技实力在商品上的集中体现,所以对手机的评价几乎可以用在汽车上,反之亦然。外观上再花里胡哨,也代替不了使用性能上的好坏,后者更是对日常来说最为重要的需求。这齐上线!小米公布15款支持升级Win11笔记本电脑目前,小米官网现已公布支持升级至Windows11的小米红米笔记本电脑,包括小米笔记本Pro14小米笔记本Pro15OLED小米笔记本ProX等搭载第8代英特尔处理器及更高版本的机谷歌相机VS米柚相机(一)多云下午3点左右光线充足手机型号小米CC9pro米柚版本12。5谷歌相机版本GCam7。3。018相机型号(如图)除单独备注外,所有的图片均是前米柚后谷歌米柚后主摄谷歌后主摄米柚50mm谷歌50mm米柚5如何搭建学习型iPad?学生党开学必备5个电子好物还有一周不到,学生党们都即将开启全新的学习历程啦!作为过来人的我给你们整理一下自己使用过的电子好物,提高学习效率。iPad配件清单附上,颜值超高!!!蓝牙耳机耳机我真的用过好几种,性能堪比戴森!云米无线吸尘器799到手一款好用的吸尘器,究竟该有哪些核心指标?10万转级别的无刷电机100AW以上的吸力灰尘气旋分离技术还有尽可能长的续航。云米VXXC09手持无线吸尘器目前开启特惠,原价899现在下单开学季蓝牙耳机推荐,便宜质量又好的学生蓝牙耳机这个暑假马上就要过去了,面对即将到来的新学期,同学们是否准备好了开学装备呢?趁着开学之际,今天就给同学们分享一些平价好用的学生蓝牙耳机,让校园生活多姿多彩!1Xisem西圣Ava推HT38全真无线蓝牙耳机,俘获你少女的心灵HT38全真无线蓝牙耳机声而不凡,妙不可言蒙蒙龙皮卡丘等天使萌穷亲情加入俘获你稚嫩的少女心升级13MM真铜环动圈喇叭,聚酯薄膜振膜,双倍加厚音圈,比其他动圈驱动更震撼的原声,善于捕
谷歌被指操纵搜索结果长达14年,瑞典比价公司索赔21亿欧元南方财经全媒体记者李润泽子广州报道当地时间2月7日,瑞典购物比价公司PriceRunner表示,该公司已经在斯德哥尔摩的法院起诉谷歌。PriceRunner指控谷歌通过操纵搜索结果德尔玛冲击创业板小米集团为第一大客户去年前三季度毛利率降低4。84个百分点中华网财经2月11日讯中华网财经了解到,广东德尔玛科技股份有限公司(以下简称德尔玛)日前更新招股说明书,拟深交所创业板挂牌上市,中金公司担任保荐人。德尔玛本次公开发行股票的数量不超工作有趣又充满挑战海外员工畅谈与华为共同成长经历据智利美洲经济网站近日报道,自1987年成立以来,对于华为这家中国跨国公司而言,员工一直是其成长和向拉丁美洲扩张的关键,目前华为在拉美拥有超过9。64万名员工。据美国福布斯杂志报道震动拖地,高效清洁米家扫拖机器人2深度体验评测熟悉我的朋友们,应该都知道我是一个特别依赖扫拖机器人的人,之所以我会如此依赖扫拖机器人,其实最主要的一点就是方便,在以前没有扫拖机器人的时候,要打扫卫生就只能用扫把和拖把给全家进行因为iPadmini6的果冻屏问题苹果遭遇集体诉讼根据MacRumors发现的法庭文件显示,科罗拉多州居民ChristopherBryan周三对苹果公司提起集体诉讼,指控苹果欺诈性地营销和销售第六代iPadmini,声称该公司知道当下30005000元的最强手机我只说这五款,随便选不花冤枉钱侃哥还记得五六年前,一款手机新手机起售价格如果可以做到3000元,消费者基本都会三思而后行而随着供应链元器件成本的增加,以及国产手机品牌集体冲击高端旗舰市场,30005000元价位当下最强的4款影像手机,华为永不落败,苹果稳扎稳打如今各大厂商基本上都把手机影像作为争相比较的一个重要配置,从去年的发布会看过来能够发现大家都会在影像方面做文章,并且会和友商做对比,那么截止今年2月份,当下最强的五款影像旗舰手机都互联网医院在未来院外处方中的发展趋势未来,决定院外处方流转最终形态的两个大事件1。药品双通道的落地,院外DTP药房成功实现院内外联动医保报销,真正实现医药的院外处方闭环,加速院内处方流转至院外2。京东健康阿里健康几大蔡司tooz发布处方近视智能眼镜,采用全彩MicroLED曲面波导透镜(映维网Nweon资讯)由德国电信和蔡司合资创办的智能眼镜厂商tooz日前宣布,与MicroLED微显示器厂商JBD(JadeBirdDisplay上海显耀显示科技)达成了战略合作为什么懂手机的都会选iQOO9Pro?因为现在懂的太多了,懂不懂都可以选择iQOO9Pro,毕竟性能配置在那里摆着。主要还是个人喜欢把。你说,骁龙8Gen1处理器增强型LPDDR5和满血版UFS3。1,目前最搭的性能铁中美欧相继拿出新动作,芯片市场或洗牌,刘德音并不看好目前,全球芯片供应依旧处于较为紧张的状态,据美方之前公布的数据,各大半导体企业的库存量仅剩5天,这与之前40天的库存量形成鲜明对比。之后,美方也给出一些建议,简单来说,就是各自想办