🎖️typeScrpt中如何从类派生接口?

简介: 在面向对象编程(OOP)中,通常我们会定义接口,并在不同的类中实现这些接口。但在 TypeScript 中,我们也可以进行反向操作,即从一个类中派生一个接口,而无需实际定义这个接口

嗨,大家好!这里是道长王jj~ 🎩🧙‍♂️

在面向对象编程(OOP)中,通常我们会定义接口,并在不同的类中实现这些接口。但在 TypeScript 中,我们也可以进行反向操作,即从一个类中派生一个接口,而无需实际定义这个接口。这种做法在多种场景下非常有用,比如为 JavaScript 类创建类型安全的模拟。这能确保模拟类实现了原始类的所有方法,而无需额外定义独立的接口。

提取实例类型

首先,我们需要从类中提取实例类型。默认情况下,当你在 TypeScript 中检索类的类型时,你会获得类的构造函数类型,而不是该类实例的类型。为了获得实例类型,我们可以定义一个实用型:

type ExtractInstanceType<T> = T extends new (...args: any[]) => infer R ? R : T extends {
    prototype: infer P } ? P : any;

这里的 ExtractInstanceType<T> 首先尝试从类的构造函数中推断实例类型。如果构造函数不可公开访问,它会从类的原型属性中推断实例类型。这与 TypeScript 内置的 InstanceType<T> 工具类型的主要区别在于,后者只适用于公开的构造函数。

考虑以下带有私有构造函数的类:

class SomeClass {
   
  private constructor() {
   }
  someMethod() {
   }
}

//> OK: 类型为 SomeClass
type SomeClassInstance = ExtractInstanceType<typeof SomeClass>; 

//> Error: 类型 'typeof SomeClass' 无法满足约束 'abstract new (...args: any) => any'。
type SomeClassInstanceError = InstanceType<typeof SomeClass>

从实例类型中提取方法

一旦我们有了实例类型,我们可以提取出它的方法。为此,我们可以定义另外两个实用型:

type ExtractMethodNames<T> = {
    [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never }[keyof T];
type ExtractMethods<T> = Pick<T, ExtractMethodNames<T>>;

ExtractMethodNames<T> 是一个映射类型,它遍历 T 的所有属性,并检查每个属性是否对应于一个方法。如果是方法,则保留该属性的键;否则,将该键分配为 never 类型。

ExtractMethods<T> 利用 Pick 工具类型从 T 中仅选择那些属于方法的属性。

现在,让我们使用这些实用型从 SomeClassInstance 中提取方法:

type SomeClassMethods = ExtractMethods<SomeClassInstance>;

在这个示例中,SomeClassMethods 是仅包含 SomeClass 实例方法的类型。

使用提取的方法实现类

最后,我们来看看如何定义一个实现了 SomeClassMethods 类型的新类。通过确保类的类型为 SomeClassMethods,我们可以确保该类具有与 SomeClass 实例相同的方法。

//> OK: 类实现了 SomeClass 中的方法
class SomeClassMock implements SomeClassMethods {
   
  someMethod() {
   }
}

//> Error: 类 'SomeClassMockError' 不正确地实现了接口 'SomeClassMethods'。
//> 类型 'SomeClassMockError' 中缺少属性 'someMethod',但在类型 'SomeClassMethods' 中是必需的
class SomeClassMockError implements SomeClassMethods {
   
  anotherMethod() {
   }
}

在这段代码中,SomeClassMock 是一个实现了 SomeClassMethods 类型的新类。这确保了 SomeClassMock 包含了 someMethod 函数。如果 SomeClassMock 不包含 someMethod 函数,或者 SomeClassMock 中的 someMethod 函数与 SomeClassMethods 中的函数不匹配,TypeScript 将引发编译错误。🛠️


🎉 你觉得怎么样?这篇文章可以给你带来帮助吗?当你处于这个阶段时,你发现什么对你帮助最大?如果你有任何疑问或者想进一步讨论相关话题,请随时发表评论分享您的想法,让其他人从中受益。🚀✨

目录
相关文章
|
12天前
|
Linux 虚拟化 iOS开发
macOS Tahoe 26.1 (25B78) 正式版 ISO、IPSW、PKG 下载
macOS Tahoe 26.1 (25B78) 正式版 ISO、IPSW、PKG 下载
327 0
macOS Tahoe 26.1 (25B78) 正式版 ISO、IPSW、PKG 下载
|
10月前
|
机器学习/深度学习 人工智能 云计算
Intel 平台新特性助力龙蜥 OS 云计算 | 龙蜥大讲堂101期
本次分享的主题是Intel平台新特性助力龙蜥OS云计算。内容涵盖英特尔第四代和第五代至强处理器的新特性,如性能提升、内置加速器等,并详细介绍TDX、SGX、AMX等技术原理及其在虚拟化环境中的支持情况,旨在帮助云用户充分利用英特尔新平台的优势。
246 5
|
编解码 搜索推荐
如何搭建一个手机网站?
随着移动端广泛使用,网站展示已经不限于PC端,更重要是移动端(手机端)的展示。我们做公司宣传,有需要拥有一个适配手机屏幕的网站变得至关重要,那么制作一个手机网站有什么步骤呢?
513 1
|
8月前
|
存储 前端开发 API
HarmonyOSNext 端云一体化(5)
本文介绍了 HarmonyOS Next 中客户端操作云存储的详细方法,涵盖云存储基础、环境准备及核心 API 使用。首先讲解了云存储的概念、免费配额与计费策略,接着说明如何在 AGC 平台开通云存储并初始化实例。核心功能包括文件上传(`uploadFile`)、云端文件列表查看(`list`)、元数据获取(`getMetadata`)、下载地址获取(`getDownloadURL`)、文件下载(`downloadFile`)和文件删除(`deleteFile`)。文中还强调了操作时需注意的事项,如文件路径限制和错误处理。通过学习,开发者可掌握云存储的基本操作,满足应用开发中的文件存储需求。
268 9
HarmonyOSNext 端云一体化(5)
|
前端开发 JavaScript
使用 JavaScript 实现图片预览功能
使用 JavaScript 实现图片预览功能
342 0
|
机器学习/深度学习 数据挖掘 物联网
【专栏】机器学习如何通过预测性维护、负载预测、动态冷却管理和能源效率优化提升数据中心能效
【4月更文挑战第27天】随着信息技术发展,数据中心能耗问题日益突出,占全球电力消耗一定比例。为提高能效,业界探索利用机器学习进行优化。本文讨论了机器学习如何通过预测性维护、负载预测、动态冷却管理和能源效率优化提升数据中心能效。然而,数据质量、模型解释性和规模化扩展是当前挑战。未来,随着技术进步和物联网发展,数据中心能效管理将更智能自动化,机器学习将在实现绿色高效发展中发挥关键作用。
329 5
|
存储 缓存 安全
阿里云EMR数据湖文件系统: 面向开源和云打造下一代 HDFS
本文作者详细地介绍了阿里云EMR数据湖文件系统JindoFS的起源、发展迭代以及性能。
73042 79
|
数据采集
遥感语义分割数据集中的切图策略
该脚本用于遥感图像的切图处理,支持大尺寸图像按指定大小和步长切割为多个小图,适用于语义分割任务的数据预处理。通过设置剪裁尺寸(cs)和步长(ss),可灵活调整输出图像的数量和大小。此外,脚本还支持标签图像的转换,便于后续模型训练使用。
122 0
|
自动驾驶 算法 搜索推荐
面向电商家居行业3D室内场景合成中的空间感知(2)
面向电商家居行业3D室内场景合成中的空间感知
274 5
|
调度 Python
能源系统工程是系统工程的一个分支,专注于能源系统的预测、规划、管理和优化。
能源系统工程是系统工程的一个分支,专注于能源系统的预测、规划、管理和优化。