Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
在TypeScript中为自定义类型数组扩展功能方法_创想鸟

在TypeScript中为自定义类型数组扩展功能方法

在TypeScript中为自定义类型数组扩展功能方法

本文探讨了在typescript中为自定义类型数组添加自定义查找函数的方法,以避免重复的`find`调用。通过结合使用typescript的交叉类型和javascript的`object.assign()`,开发者可以优雅地将`findbyid`、`findbyname`等方法附加到数组实例上,实现更简洁、类型安全的代码,同时兼顾`find`方法可能返回`undefined`的情况。

在TypeScript项目中,我们经常会遇到需要对特定类型的数组进行频繁查找操作的场景。例如,一个包含用户对象的数组,我们可能需要根据用户ID或用户名来查找特定的用户。虽然原生的Array.prototype.find()方法能够完成这项任务,但当相同的查找逻辑在代码库的不同位置重复出现时,这不仅会导致代码冗余,也降低了可维护性。本文将介绍一种优雅且类型安全的方法,在不修改原生Object或Array原型的情况下,为自定义类型数组实例扩展自定义的查找方法。

1. 问题背景:重复的数组查找

假设我们有一个自定义类型A的数组,其中每个元素包含id和name属性:

type A = {  id: number;  name: string;};const data: A[] = [  { id: 1, name: 'Foo' },  { id: 2, name: 'Bar' },  // ...更多数据];

当我们频繁需要根据id或name查找数组中的元素时,代码可能会变成这样:

const entryById = data.find((item) => item.id === 1);const entryByName = data.find((item) => item.name === 'Foo');

这种模式在多处重复时,不仅增加了代码量,也使得未来修改查找逻辑变得复杂。我们的目标是能够像下面这样调用:

const entryById = data.findById(1);const entryByName = data.findByName('Foo');

2. 解决方案:结合TypeScript交叉类型与Object.assign()

为了实现上述目标,我们可以利用TypeScript的交叉类型(Intersection Types)来定义一个既是数组又包含额外方法的类型,然后使用JavaScript的Object.assign()方法将这些方法实际附加到数组实例上。

2.1 类型定义

首先,我们需要定义一个扩展后的数组类型。这个类型将是原始数组类型A[]与一个包含自定义方法的对象类型{ findById: (id: number) => A | undefined; findByName: (name: string) => A | undefined; }的交叉类型。

type A = {  id: number;  name: string;};// 定义扩展后的数组类型type ExtendedAArray = A[] & {  findById: (id: number) => A | undefined;  findByName: (name: string) => A | undefined;};

这里需要注意的是,Array.prototype.find()方法在找不到匹配项时会返回undefined。因此,我们的自定义查找方法也应将undefined作为可能的返回类型,以保持类型安全。

2.2 使用Object.assign()附加方法

Object.assign()方法用于将所有可枚举的自有属性从一个或多个源对象复制到目标对象。它会返回目标对象。我们可以将一个普通数组作为目标对象,然后将包含自定义方法的对象作为源对象,从而将这些方法“混合”到数组实例上。

const data: ExtendedAArray = Object.assign(  [    { id: 1, name: 'Foo' },    { id: 2, name: 'Bar' },    { id: 3, name: 'Baz' },  ],  {    findById: function (this: ExtendedAArray, id: number): A | undefined {      // 在方法内部,this指向当前的ExtendedAArray实例      return this.find((a) => id === a.id);    },    findByName: function (this: ExtendedAArray, name: string): A | undefined {      return this.find((a) => name === a.name);    },  });

在上述代码中,我们直接在Object.assign的第二个参数中定义了findById和findByName方法。这些方法内部使用了this关键字来引用当前数组实例,从而能够调用原生的find方法。为了确保this的类型正确,我们显式地为this参数添加了ExtendedAArray类型注解。

2.3 完整示例代码

下面是一个完整的示例,展示了如何定义类型、创建扩展数组并使用自定义方法:

type A = {  id: number;  name: string;};// 定义扩展后的数组类型,包含自定义查找方法type ExtendedAArray = A[] & {  findById: (id: number) => A | undefined;  findByName: (name: string) => A | undefined;};// 使用 Object.assign() 创建并扩展数组实例const data: ExtendedAArray = Object.assign(  [    { id: 1, name: 'Foo' },    { id: 2, name: 'Bar' },    { id: 3, name: 'Baz' },  ],  {    // 定义自定义查找方法    findById: function (this: ExtendedAArray, id: number): A | undefined {      return this.find((item) => id === item.id);    },    findByName: function (this: ExtendedAArray, name: string): A | undefined {      return this.find((item) => name === item.name);    },  });// 调用扩展后的方法console.log('通过ID查找 (ID 1):', data.findById(1)?.name); // 输出: Fooconsole.log('通过名称查找 (Name Foo):', data.findByName('Foo')?.id); // 输出: 1// 查找不存在的元素,将返回 undefinedconsole.log('查找不存在的ID (ID 4):', data.findById(4)); // 输出: undefinedconsole.log('查找不存在的名称 (Name Quux):', data.findByName('Quux')); // 输出: undefined// 仍然可以使用原生数组方法console.log('原生数组长度:', data.length); // 输出: 3

3. 注意事项与最佳实践

类型安全至关重要: 正确定义交叉类型A[] & { … }是确保TypeScript能够识别新方法的关键。如果缺少这个类型定义,TypeScript会认为data只是一个普通的A[],从而报错。处理undefined: Array.prototype.find()在找不到匹配项时会返回undefined。因此,您的自定义方法也应该返回A | undefined。在使用这些方法的返回值时,务必进行空值检查,例如使用可选链操作符?.或空值合并操作符??,或者在业务逻辑中抛出异常。this上下文: 在使用function关键字定义方法时,this的指向取决于函数的调用方式。在Object.assign的场景下,this将正确指向被扩展的数组实例。为了类型安全,建议显式地为this参数添加类型注解(如this: ExtendedAArray)。如果使用箭头函数,this将指向其定义时的词法作用域,这可能不符合预期,除非您希望方法内部不依赖this。避免修改原型: 这种方法避免了直接修改Array.prototype或Object.prototype。修改原型可能会导致全局污染,与其他库或未来的JavaScript版本产生冲突,因此通常不推荐。封装性: 这种方法提供了一种良好的封装机制,将特定的查找逻辑与数据结构紧密结合,提高了代码的可读性和模块化程度。性能考量: 每次调用自定义查找方法时,底层仍然会执行一次Array.prototype.find()。对于超大型数组或极度频繁的查找,如果性能成为瓶颈,可能需要考虑其他数据结构(如Map)或索引优化方案。

4. 总结

通过巧妙地结合TypeScript的交叉类型定义和JavaScript的Object.assign()方法,我们能够为自定义类型的数组实例添加强大的、类型安全的自定义功能方法。这种模式不仅提升了代码的表达力和可读性,还避免了全局污染的风险,是处理特定数组查找逻辑重复问题的一种专业且高效的解决方案。开发者可以根据具体需求,扩展更多类似的功能方法,使代码更加健壮和易于维护。

以上就是在TypeScript中为自定义类型数组扩展功能方法的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1530984.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
获取 nipple.js 虚拟摇杆的实时位置与距离数据
上一篇 2025年12月20日 22:27:53
JavaScript虚拟DOM性能对比
下一篇 2025年12月20日 22:28:03

相关推荐

  • Java Collections.sort与Collections.reverse的使用区别

    Collections.sort用于排序,基于元素值比较,结果有序,默认升序,可自定义规则;2. Collections.reverse仅反转列表顺序,不比较元素,时间复杂度O(n);3. 两者功能不同,不可替代,按需选择使用。 Java 中 Collections.sort 和 Collectio…

    2026年9月21日
    100
  • Bun 1.3 正式发布

    2025年10月10日,高性能 javascript 运行时 bun 发布了 1.3 版本。这是 bun 项目迄今为止最重大的版本更新,标志着 bun 从单纯的运行时工具演变为一个功能完备的全栈 javascript 开发平台。 从运行时到全栈平台的跨越 Bun 1.3 的核心突破在于将前端开发能力…

    2026年9月21日
    000
  • Java中多态的基本实现方法

    多态允许同一接口调用不同实现,通过继承与方法重写实现。1. 子类重写父类方法,如Animal的makeSound被Dog和Cat重写;2. 父类引用指向子类对象,运行时动态绑定,如Animal myPet = new Dog()调用Woof;3. 方法参数使用父类类型,提升代码复用,如playWit…

    2026年9月21日
    000
  • safari浏览器如何设置链接在新窗口而不是新标签页打开_safari浏览器链接新窗口打开设置

    通过快捷键或第三方扩展可实现Safari中链接在新窗口打开:1. 按住Command键点击链接可临时在新窗口打开;2. 使用AppleScript脚本通过“自动操作”创建快速操作以新建Safari窗口;3. 网站自身代码如window.open()会强制新窗口打开;4. 安装可信扩展如“Link i…

    2026年9月21日
    000
  • Hibernate Search嵌入式对象索引策略与常见问题解决

    本文探讨了在使用Hibernate Search对关联或嵌入式对象进行索引时遇到的常见问题,特别是@IndexedEmbedded与includePaths属性的结合使用。通过分析HSEARCH000216错误,揭示了嵌入式对象属性需要显式@Field注解才能被主实体索引的机制,并提供了具体的代码示…

    2026年9月21日
    100
  • 在Java中如何实现对象的唯一标识

    答案:Java中实现对象唯一标识主要有四种方式:1. 使用UUID生成全局唯一ID,适用于无数据库或分布式场景;2. 利用数据库自增主键,通过JPA的@Id和@GeneratedValue实现持久化唯一性;3. 重写equals与hashCode方法,基于不可变业务字段保证逻辑唯一;4. 采用Sno…

    2026年9月21日
    000
  • VSCode语言特性贡献点配置

    通过配置package.json中的contributes字段可实现VSCode语言扩展,依次需设置语法高亮(grammars)、语言绑定(languages)、激活事件(activationEvents)及语言服务器功能(如补全、跳转),并定义language-configuration.json…

    2026年9月21日
    000
  • 使用本地HTML文件运行JavaScript脚本失败的原因及解决方案

    本文旨在帮助开发者理解在没有Web服务器的情况下,直接通过浏览器打开本地HTML文件时,JavaScript脚本可能无法正常运行的原因,并提供相应的解决方案。文章将深入探讨浏览器安全策略、相对路径问题以及如何正确引入和执行JavaScript脚本,确保你的HTML、CSS和JavaScript代码能…

    2026年9月21日
    000
  • VSCode怎么看效果_VSCode实时预览和调试代码运行效果教程

    VSCode通过实时预览扩展和内置调试器实现代码效果查看。使用Live Server可实时预览前端页面,保存即刷新;Markdown文件支持侧边预览。调试功能需配置launch.json,支持Node.js、Python、浏览器端JavaScript等,通过断点、变量监视、调用堆栈等深入分析代码执行…

    2026年9月21日
    000
  • 使用正则表达式检测字符串中的除零操作

    本文详细介绍了如何使用正则表达式精确检测字符串中潜在的除零操作。针对表达式中可能存在的变量引用(如<>)、数字、多余空格以及禁止包含引号等复杂情况,文章提供了一个高效的正则表达式模式,并深入解析其构成原理。通过具体的Java代码示例,读者将学习如何将此模式应用于实际编程场景,从而有效识别…

    2026年9月21日
    000
  • 构建Spring自定义Kafka配置的注解式解决方案

    本文探讨了在Spring Boot应用中通过自定义注解实现Kafka配置自动化时遇到的挑战,特别是由于Bean注册时机不当导致的依赖注入失败。我们将深入分析问题根源,并提供两种核心解决方案:利用META-INF/spring.factories实现标准化的自动配置发现,以及通过ImportBeanD…

    2026年9月21日
    1100
  • 悟空浏览器开发者工具的控制台怎么用_悟空浏览器Console控制台使用入门教程

    首先启用悟空浏览器开发者工具并进入Console标签,可查看错误、警告等日志信息,通过过滤功能定位问题;支持执行JavaScript代码实时调试,监控网络请求失败及全局异常,还可清空或保存日志以便分析。 如果您在使用悟空浏览器进行网页开发或调试时,发现页面元素未按预期工作或脚本报错,则可以借助开发者…

    2026年9月21日
    700
  • 实现搜索结果的 A-Z 排序:PHP 教程

    本文档旨在指导开发者如何在 PHP 中实现搜索结果的 A-Z 排序功能。通过结合 AJAX 技术和 PHP 函数,可以方便地对通过 POST 方法获取的医生搜索结果进行 A-Z 排序,从而优化用户浏览体验。本文将详细介绍实现步骤,提供可复用的代码示例,并着重强调注意事项,旨在帮助开发者快速掌握并应用…

    2026年9月21日
    000
  • Java中高效查找时空事件重叠的方法

    本文探讨了在Java中高效查找具有空间和时间范围定义的事件之间重叠的解决方案。核心思想是将时空事件编码为二维矩形,然后利用专业的空间索引结构(如R树、四叉树或PH树)进行快速查询。通过这种方法,可以显著提升在大规模数据集中识别事件重叠的效率,并提供了使用Tinspin索引库的示例代码和实践建议。 时…

    2026年9月21日
    100
  • 使用EventBus实现Android实时速度显示与后台保存教程

    本教程详细介绍了如何在Android应用中实现实时速度的显示与后台保存功能。通过利用前台服务(Foreground Service)获取位置数据,并结合EventBus库实现服务与UI界面(MainActivity)之间的实时数据通信,确保即使应用处于后台或屏幕关闭时,速度数据也能持续更新并显示在用…

    2026年9月21日
    000
  • 在Java中如何分析异常堆栈性能开销

    异常堆栈在高并发场景下开销显著,因JVM需遍历调用栈、创建对象、字符串拼接及同步操作,频繁使用将增加GC压力与CPU消耗;可通过JMH测试量化影响,发现填充堆栈耗时可达清空的10倍以上;建议避免在热点代码抛异常、禁用非必要堆栈填充、按需打印日志、使用异步日志框架,并借助JFR、Profiler和GC…

    2026年9月21日
    000
  • VSCode报错怎么显示中文_VSCode错误信息本地化与中文显示教程

    安装中文语言包可将VSCode界面和错误提示转为中文,提升使用便捷性;但外部工具如编译器、解释器生成的报错仍为英文,因VSCode仅显示其原始输出,无法翻译。 在VSCode中让报错信息显示中文,核心在于安装并启用官方的中文(简体)语言包。这不仅仅是针对错误信息,而是将整个VSCode的用户界面本地…

    2026年9月21日
    300
  • Java ConcurrentSkipListMap在并发场景下应用

    ConcurrentSkipListMap是基于跳跃表实现的线程安全有序映射,支持高并发读写与高效范围查询,适用于需排序的并发场景,如排行榜系统;相比ConcurrentHashMap,它提供有序性与导航操作,但插入查找为O(log n),内存开销较大,适合读多写少或需区间扫描的业务。 在高并发场景…

    2026年9月21日
    100
  • VSCode怎么设置变量窗口_VSCode调试时变量监视面板使用教程

    答案:配置launch.json并设置断点后,通过VSCode调试界面的变量和监视面板可实时查看变量值。具体包括正确设置program路径,利用变量面板查看作用域内变量,使用监视面板添加表达式或变量进行持续跟踪,结合调试按钮控制执行流程,并可通过条件断点、控制台输出、debugger语句、Sourc…

    2026年9月21日
    100
  • Java 正则表达式:查找双引号内所有指定字符串的出现次数

    本文旨在解决在 Java 中使用正则表达式查找双引号内特定字符串(例如 “variant”)的所有出现次数的问题。我们将提供一个完整的解决方案,包括正则表达式的构建、代码示例以及详细的解释,帮助开发者准确高效地完成此类任务。 在 Java 中,使用正则表达式查找字符串中特定模…

    2026年9月21日
    000

发表回复

登录后才能评论
关注微信