Typescript高级: 深入理解ConstructorParameters类型及借助infer构建带参数的工厂实例方法

概述

  • 在TypeScript中,利用泛型和类型推断,我们可以编写出既灵活又安全的代码
  • 特别是在处理类和其实例化过程中,这些特性显得尤为重要
  • 我们着重关注构造函数参数(constructor parameters)的类型处理
  • 以及如何利用泛型工厂函数来创建类的实例
  • 构造函数是面向对象编程中初始化对象状态的核心手段
  • 在TypeScript中,通过为构造函数及其参数添加类型注解
  • 可以确保在创建对象时遵循预定义的类型规则,从而提高程序的健壮性

应用示例

// 定义一个简单的类  
class TestClass {public name: string;public classno: number;constructor(name: string, classno: number) {this.name = name;this.classno = classno;}greet() {  console.log(`Hello, my name is ${this.name} and I'm in class ${this.classno}.`);  }  
}  // 定义构造函数类型和构造函数参数类型  
type Constructor<T> = new (...args: any[]) => T;  
type ConstructorParametersType<T extends Constructor<any>> = T extends new (...args: infer P) => any ? P : never;  // 泛型工厂函数  
function createInstance<T>(constructor: Constructor<T>, ...args: ConstructorParametersType<Constructor<T>>): T {  return new constructor(...args);  
}  // 使用泛型工厂函数创建TestClass的实例并调用其方法  
const instance = createInstance(TestClass, "Alice", 123);  
instance.greet(); // 输出:Hello, my name is Alice and I'm in class 123.

1 ) ConstructorParametersType

  • TypeScript提供了ConstructorParameters内置类型
  • 它能够自动提取构造函数的参数类型
  • 但为了深入理解其原理,我们先自定义一个ConstructorParametersType
    type ConstructorParametersType<T extends new (...args: any[]) => any>= T extends new (...args: infer P) => any ? P : never;
    
  • 这段代码展示了TypeScript的条件类型与infer关键字的强大功能
  • 它定义了一个泛型类型T,要求T是一个构造函数类型
  • 即接受任意数量参数并返回某个类型的构造函数
  • 通过infer P,我们可以从T中推断出实际的参数类型数组P,最终作为输出类型
  • 如果T不符合预期构造函数类型,则默认返回never,确保类型安全

2 ) 泛型工厂函数:动态实例化的桥梁

  • 接下来,我们利用ConstructorParametersType来实现一个高度灵活的工厂函数createInstance

  • 此函数接收两个泛型参数:T代表要实例化的类的类型,而CP约束为对应的构造函数类型

  • 函数体内的类型声明 ...args: ConstructorParametersType<CP>保证了传入的参数与构造函数期望的参数类型完全匹配

    function createInstance<T, CP extends new (...args: any[]) => any>(constructor: CP,...args: ConstructorParametersType<CP>
    ): InstanceType<CP> {return new constructor(...args);
    }
    
  • 这里, InstanceType<CP> 是另一个TypeScript内置类型

  • 用于从构造函数类型推断出实例类型,确保返回值具有正确的类型

3 ) 总结

  • 在这个示例中,我首先定义了一个 TestClass
  • 它有一个构造函数接受 nameclassno 作为参数,并有一个eat方法用于打印学生信息
  • 之后,定义了一个工厂函数 createInstance
  • 它使用了TypeScript的内置类型 ConstructorParameters<T>来获取构造函数的参数类型
  • 以及InstanceType<T>来表示构造函数实例的类型,这样就不需要手动定义ConstructorParametersType
  • 通过这种方式,createInstance函数变得更加简洁且直接,同时仍然保持了类型安全,确保传入的参数类型与构造函数参数类型严格匹配
  • 最后,通过调用createInstance函数创建了TestClass的一个实例并调用了eat方法来验证功能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/845990.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IP路由策略1

控制层面:路由协议传递路由信息的流量--对应的方向 数据层面:设备间具体访问时请求的流量--对应方向 控制层面方向与数据层面方向一定相反 在控制层面流量进或出的接口上&#xff0c;抓取流量后&#xff0c;修改其中参数或删除该信息&#xff0c;最终起到影响路由器路由表的生…

「Django秘境探险:揭开Web开发的神秘面纱」

大家好&#xff0c;我是阿佑&#xff0c;今天将和大家一块学习到如何利用Django框架的高级特性&#xff0c;构建出既快速又安全的Web应用。我们将一起破解Django的内部机制&#xff0c;掌握从数据模型到模板设计的每一个环节。准备好了吗&#xff1f;Let’s go &#xff01; 文…

“手撕”链表的九道OJ习题

目录 1. 第一题 2. 第二题 3. 第三题 4. 第四题 5. 第五题 6. 第六题 7. 第七题 8. 第八题 9. 第九题 1. 第一题 删除链表中等于给定值 val 的所有节点。OJ链接 思路如下&#xff1a; 相当于链表的removeAll();制定prev和cur&#xff0c;prev记录前一个节点&#xff…

MySQL学习——行分类及日期计算

1 行分类 你可能已经在前面的例子中注意到&#xff0c;结果行的显示没有特定的顺序。当结果行以某种有意义的方式进行排序时&#xff0c;检查查询输出通常会更容易。要对结果进行排序&#xff0c;请使用ORDER BY子句。 以下是按日期排序的动物生日&#xff1a; mysql> SE…

Windows11 wsl2编译Android14 使用ASfP Debug windows上启动的模拟器

wsl2的安装和配置 安装&#xff1a; 直接百度搜索最新的wsl2安装教程即可&#xff0c;官网&#xff1a;https://learn.microsoft.com/zh-cn/windows/wsl/install 1. 启用适用于 Linux 的 Windows 子系统(以管理员身份打开 PowerShell 并运行) Enable-WindowsOptionalFeature…

Nginx的Map模块

Nginx的map模块是一个功能强大的工具&#xff0c;可以在配置Nginx时实现更高效的请求处理。本文将介绍map模块的基本用法、使用场景、示例以及注意事项。 什么是Nginx的map模块&#xff1f; Nginx的map模块允许我们根据变量的值来映射到对应的值。这个映射可以是静态的&#…

8-Django项目--登录及权限

目录 templates/login/login.html templates/login/404.html views/login.py utils/pwd_data.py auth.py settings.py 登录及权限 登录 views.py 中间件 auth.py templates/login/login.html {% load static %} <!DOCTYPE html> <html lang"en"&g…

Linux系统编程——动静态库

目录 一&#xff0c;关于动静态库 1.1 什么是库&#xff1f; 1.2 认识动静态库 1.3 动静态库特征 二&#xff0c;静态库 2.1 制作静态库 2.2 使用静态库 三&#xff0c;动态库 3.1 制作动态库 3.2 使用动态库一些问题 3.3 正确使用动态库三种方法 3.3.1 方法一&…

什么是BFC?

1、BFC&#xff1a;又叫块级格式化上下文&#xff08;block formatting context&#xff09;&#xff0c;就是页面上一个隔离的独立容器&#xff0c;容器里面的子元素不会影响到外面的元素。 2、BFC的原则&#xff1a;如果一个元素具有BFC&#xff0c;那么内部元素再怎么弄&am…

微信小程序的tabbar怎么配置

微信小程序的tabBar配置是在全局配置文件app.json中进行的&#xff0c;主要用于设置小程序底部的导航栏效果。以下是一个清晰的tabBar配置步骤和示例&#xff1a; 1. 打开app.json文件 这个文件位于小程序项目的根目录下&#xff0c;是微信小程序的全局配置文件。 2. 添加或…

QuillEditor富文本结合vue3使用,可单独抽离成组件,富文本的内容可自定义

实现效果&#xff1a; 上方的粗体、斜体、字号、字体等各种信息支持自定义配置。 实现方式&#xff1a; 下面的介绍为分步骤的详细介绍&#xff0c;完整版纯享代码可参考这篇博客富文本QuillEditorvue3组件代码纯享版-CSDN博客 1.新建一个新文件--子组件&#xff0c;如命名为…

git应用最佳实践

插&#xff1a; AI时代&#xff0c;程序员或多或少要了解些人工智能&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家(前言 – 人工智能教程 ) 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家…

QGraphicsView实现简易地图19『迁徙图』

模仿echarts的迁徙图效果 用到了前2篇制作的散点(涟漪效果)和两年前的路径动画类&#xff1b;然尾迹效果未依附路径&#xff0c;有待优化。 动态演示效果 静态展示图片 核心代码 #pragma once #include "Item/AbstractGeoItem.h" #include "DataStruct/GeoD…

php之文件操作代码审计

1 PHP文件操作函数 1.1 PHP文件操作函数 文件包含 include/require/include_once/require_once 文件读取 file_get_contents/fread/readfile/file 文件写入 file_put_contents/fwrite/mkdir/fputs 文件删除 unlink/rmdir 文件上传 move_uploaded_file/copy/rename 1.2 文…

python使用MkDocs自动生成文档

python使用MkDocs自动生成文档 前言使用MkDocs环境相关资料使用介绍项目结构配置文件注释生成文档的配置运行与构建部署 实践的项目 前言 python代码注释风格有很多&#xff0c;比较主流的有 reStructuredText风格、numpy风格、Google风格。 自动生成文档的工具也有很多&…

IO流(1)

定义&#xff1a;存取和读取数据的解决方案 作用&#xff1a;用于读写数据&#xff08;本地文件、网络&#xff09; 分类&#xff1a; 一种是&#xff1a;输出流和输入流。 一种是&#xff1a;字节流和字符流。 字节流 字节流——FileOutputStream&#xff08;字节输出流&…

C++标准模板(STL)- 变参数函数

变参数函数 变参数函数是接收可变数量参数的函数&#xff08;例如 std::printf &#xff09;。 为声明变参数函数&#xff0c;要以省略号为最后的形参&#xff0c;例如 int printf(const char* format, ...); 。语法上的额外细节、自动参数转换及替用项见变参数。 为从函数…

L9110S电机控制模块

1.L9110s控制小车前进后退左右 接通VCC&#xff0c;GND 模块电源指示灯亮&#xff0c; 以下资料来源官方&#xff0c;但是仍需我们调制 &#xff08;前进&#xff09;&#xff1a; L1A输入低电平&#xff0c;L1B输入高电平 R1A输入低电平&#xff0c;R1B输入高电平 &a…

智能优化算法 | Matlab实现DBO蜣螂优化算法

智能优化算法 | Matlab实现DBO蜣螂优化算法 文章目录 智能优化算法 | Matlab实现DBO蜣螂优化算法文章概述源码设计文章概述 智能优化算法 | Matlab实现DBO蜣螂优化算法 源码设计 % ----------------------------------------------------------------------------------------…

(函数)判断一句话中最长的单词(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//声明函数&#xff1b; int aiphabetic(char); int longest(char[]);int main() {//初始化变量值&#xff1b;int i;char line[100] { 0 };//获取用户输入字符…