当前位置: 首页 > news >正文

小鱼在线网站建设/友情链接交换群

小鱼在线网站建设,友情链接交换群,武汉外贸网站推广方案,单位还能建设网站吗🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 TypeScript函数类型:提升函数的类型安全性和可读性1. 引言2. 基本函…

鑫宝Code

🌈个人主页: 鑫宝Code
🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础
💫个人格言: "如无必要,勿增实体"


文章目录

  • TypeScript函数类型:提升函数的类型安全性和可读性
    • 1. 引言
    • 2. 基本函数类型
      • 2.1 函数声明
      • 2.2 函数表达式
      • 2.3 箭头函数
    • 3. 可选参数和默认参数
      • 3.1 可选参数
      • 3.2 默认参数
    • 4. 剩余参数
    • 5. 函数重载
    • 6. 泛型函数
      • 6.1 泛型约束
    • 7. 函数类型接口
    • 8. 回调函数类型
    • 9. 构造函数类型
    • 10. 函数类型推断
    • 11. 高级类型与函数
      • 11.1 联合类型
      • 11.2 交叉类型
    • 12. 条件类型与函数
    • 13. 函数类型的最佳实践
    • 14. 常见陷阱和解决方案
      • 14.1 this的类型
      • 14.2 回调函数中的this
    • 15. 实际应用示例
    • 16. 结论

TypeScript函数类型:提升函数的类型安全性和可读性

1. 引言

在这里插入图片描述

在JavaScript中,函数是一等公民,它们可以被赋值给变量、作为参数传递,甚至作为其他函数的返回值。TypeScript作为JavaScript的超集,不仅继承了这些特性,还为函数添加了强大的类型系统支持。本文将深入探讨TypeScript中的函数类型,包括其定义、使用方法以及高级特性,帮助您更好地在TypeScript项目中使用函数,提高代码的类型安全性和可读性。

2. 基本函数类型

2.1 函数声明

在TypeScript中,我们可以为函数的参数和返回值添加类型注解:

function add(x: number, y: number): number {return x + y;
}

2.2 函数表达式

函数表达式也可以添加类型注解:

const multiply: (x: number, y: number) => number = function(x, y) {return x * y;
};

2.3 箭头函数

箭头函数同样支持类型注解:

const divide = (x: number, y: number): number => x / y;

3. 可选参数和默认参数

3.1 可选参数

使用?标记可选参数:

function greet(name: string, greeting?: string): string {return greeting ? `${greeting}, ${name}!` : `Hello, ${name}!`;
}

3.2 默认参数

默认参数可以与类型注解结合使用:

function createUser(name: string, age: number = 18): { name: string, age: number } {return { name, age };
}

4. 剩余参数

TypeScript支持剩余参数,并可以为其指定类型:

function sum(...numbers: number[]): number {return numbers.reduce((acc, curr) => acc + curr, 0);
}

5. 函数重载

TypeScript允许我们为同一个函数提供多个函数类型定义:

function reverse(x: string): string;
function reverse(x: number[]): number[];
function reverse(x: string | number[]): string | number[] {if (typeof x === 'string') {return x.split('').reverse().join('');} else {return x.slice().reverse();}
}

6. 泛型函数

在这里插入图片描述

泛型允许我们在定义函数时不指定具体的类型,而在使用时再指定:

function identity<T>(arg: T): T {return arg;
}let output = identity<string>("myString");

6.1 泛型约束

我们可以使用extends关键字来约束泛型类型:

interface Lengthwise {length: number;
}function loggingIdentity<T extends Lengthwise>(arg: T): T {console.log(arg.length);  // Now we know it has a .length propertyreturn arg;
}

7. 函数类型接口

我们可以使用接口来描述函数类型:

interface MathFunc {(x: number, y: number): number;
}let add: MathFunc = (x, y) => x + y;
let subtract: MathFunc = (x, y) => x - y;

8. 回调函数类型

在处理回调函数时,正确定义其类型非常重要:

function fetchData(callback: (data: string) => void): void {// 模拟异步操作setTimeout(() => {callback("Data fetched");}, 1000);
}

9. 构造函数类型

TypeScript允许我们定义构造函数的类型:

interface Point {x: number;y: number;
}interface PointConstructor {new (x: number, y: number): Point;
}function createPoint(ctor: PointConstructor, x: number, y: number): Point {return new ctor(x, y);
}

10. 函数类型推断

TypeScript能够根据上下文自动推断函数的类型:

let numbers = [1, 2, 3, 4, 5];
numbers.forEach((num) => {console.log(num.toFixed(2));  // TypeScript knows 'num' is a number
});

11. 高级类型与函数

11.1 联合类型

函数可以接受或返回联合类型:

function formatValue(value: string | number): string {if (typeof value === "string") {return value.toUpperCase();}return value.toFixed(2);
}

11.2 交叉类型

交叉类型可以用来组合多个函数类型:

type Adder = (a: number, b: number) => number;
type Multiplier = (a: number, b: number) => number;type Calculator = Adder & Multiplier;const calc: Calculator = (a, b) => a + b;  // 或 a * b

12. 条件类型与函数

条件类型可以根据条件选择不同的函数类型:

type FunctionType<T> = T extends string ? (arg: string) => string : (arg: number) => number;function processValue<T extends string | number>(value: T): FunctionType<T> {if (typeof value === "string") {return ((arg: string) => arg.toUpperCase()) as FunctionType<T>;} else {return ((arg: number) => arg * 2) as FunctionType<T>;}
}

13. 函数类型的最佳实践

  1. 明确指定返回类型:虽然TypeScript可以推断返回类型,但明确指定可以提高代码可读性和可维护性。

  2. 使用函数类型别名:对于复杂的函数类型,使用类型别名可以提高可读性:

    type AsyncCallback<T> = (error: Error | null, result: T) => void;
    
  3. 利用泛型:当函数可以处理多种类型时,优先考虑使用泛型而不是any。

  4. 使用函数重载:当函数根据不同的参数有不同的行为时,使用函数重载可以提供更精确的类型信息。

  5. 避免过度使用可选参数:过多的可选参数可能导致函数调用变得复杂,考虑使用对象参数模式。

14. 常见陷阱和解决方案

14.1 this的类型

在TypeScript中,可以明确指定this的类型:

interface User {name: string;greet(this: User): void;
}const user: User = {name: "Alice",greet() {console.log(`Hello, I'm ${this.name}`);}
};

14.2 回调函数中的this

在回调函数中,this的类型可能会丢失。使用箭头函数或显式绑定可以解决这个问题:

class Handler {info: string;onEvent(this: Handler, e: Event) {// this的类型是Handlerthis.info = e.type;}
}

15. 实际应用示例

让我们通过一个实际的应用示例来展示TypeScript函数类型的强大功能:

// 定义一个表示HTTP方法的类型
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';// 定义一个表示API端点的接口
interface ApiEndpoint<T> {url: string;method: HttpMethod;params?: object;response: T;
}// 定义一个通用的API调用函数
async function apiCall<T>(endpoint: ApiEndpoint<T>): Promise<T> {const { url, method, params } = endpoint;const response = await fetch(url, {method,body: params ? JSON.stringify(params) : undefined,headers: {'Content-Type': 'application/json'}});if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}return await response.json() as T;
}// 定义一些具体的API端点
interface User {id: number;name: string;email: string;
}const getUserEndpoint: ApiEndpoint<User> = {url: '/api/user/1',method: 'GET',response: {} as User
};const createUserEndpoint: ApiEndpoint<User> = {url: '/api/user',method: 'POST',params: { name: 'New User', email: 'newuser@example.com' },response: {} as User
};// 使用apiCall函数
async function fetchUser() {try {const user = await apiCall(getUserEndpoint);console.log('Fetched user:', user.name);} catch (error) {console.error('Error fetching user:', error);}
}async function createUser() {try {const newUser = await apiCall(createUserEndpoint);console.log('Created user:', newUser.id);} catch (error) {console.error('Error creating user:', error);}
}fetchUser();
createUser();

这个例子展示了如何使用TypeScript的函数类型和泛型来创建一个类型安全的API调用系统:

  • 使用类型别名和接口定义API相关的类型
  • 创建一个泛型函数apiCall来处理不同类型的API请求
  • 使用函数重载和条件类型可以进一步改进这个系统,以处理更复杂的场景

16. 结论

TypeScript的函数类型系统为JavaScript的函数添加了强大的类型检查和安全性。通过本文的介绍,我们探讨了从基本的函数类型定义到高级特性如泛型、条件类型等多个方面。掌握这些概念和技巧,将帮助您更有效地使用TypeScript,编写出更加健壮、可维护的代码。

在实际开发中,合理运用函数类型可以大大减少运行时错误,提高代码质量。随着您在项目中不断实践,您会发现TypeScript的函数类型系统不仅能捕获潜在的错误,还能提供更好的代码提示和自动完成功能,从而提高开发效率。

继续探索和实践,相信您会在TypeScript的类型系统中发现更多精彩,让您的函数更加安全、清晰和高效!

End

相关文章:

【TS】TypeScript函数类型:提升函数的类型安全性和可读性

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 TypeScript函数类型&#xff1a;提升函数的类型安全性和可读性1. 引言2. 基本函…...

“八股文”在实际工作中是助力、阻力还是空谈?

前言&#xff1a;在当今快速发展的技术时代&#xff0c;程序员的角色变得日益重要。随着技术的不断进步&#xff0c;招聘流程也在不断演变以适应新的需求。在程序员的招聘过程中&#xff0c;“八股文”作为一种面试现象&#xff0c;已成为不可忽视的一部分。所谓“八股文”&…...

代码随想录算法训练营第22天-leetcode-回溯算法part01:

#回溯算法理论基础 能解决的问题&#xff1a; 组合问题&#xff1a;N个数里面按一定规则找出k个数的集合切割问题&#xff1a;一个字符串按一定规则有几种切割方式子集问题&#xff1a;一个N个数的集合里有多少符合条件的子集排列问题&#xff1a;N个数按一定规则全排列&…...

MySql 触发器、存储器练习

一&#xff1a; 触发器 1、建立两个表:goods(商品表)、orders(订单表) 查看数据库&#xff1a;mysql> show databases; 使用数据库&#xff1a;mysql> use mydb16_trigger; 创建goods表&#xff1a; mysql> create table goods(gid char(8) not null primary key, …...

【Plotly-驯化】一文教您画出Plotly中动态可视化饼图:pie技巧

【Plotly-驯化】一文教您画出Plotly中动态可视化饼图&#xff1a;pie技巧 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 免费获取相关内…...

Mirror学习笔记(一) 简介

文章目录 一、常规学习&#xff1a;Mirror核心功能有服务器和主机 二、时间戳批处理时间戳 三、TCP和UDP四、CCU(同时在线人数)五、SyncDirection(同步方向)六、RTT&#xff08;往返时间&#xff09;七、Connection Quality&#xff08;连接质量&#xff09;八、Lag Compensati…...

终端pip安装包后,Pycharm却导入失败?新手别慌,3招搞定!

很多小伙伴在学习Python的过程中,都会遇到这种情况:明明在终端用pip安装好了需要的包,但在Pycharm中导入时却报错。难道是安装姿势不对? 例如在cmd中已经有了pandas,但是去pycharm中导入pandas显示没有 先别急着怀疑人生,这很可能是因为pip安装包的路径和Pycharm项目使用…...

Redis 与 Scrapy:无缝集成的分布式爬虫技术

1. 分布式爬虫的概念 分布式爬虫系统通过将任务分配给多个爬虫节点&#xff0c;利用集群的计算能力来提高数据抓取的效率。这种方式不仅可以提高爬取速度&#xff0c;还可以在单个节点发生故障时&#xff0c;通过其他节点继续完成任务&#xff0c;从而提高系统的稳定性和可靠性…...

大厂linux面试题攻略四之Linux网络服务(一)

一、Linux网络服务-SSH服务 1.哪些设置能够提升SSH远程管理的安全等级? ssh的登录验证方式 ssh的登录端口和监听设置&#xff1a; 配置文件: /etc/ssh/sshd_config #Port 22 #ssh服务默认监听端口 #ListenAddress 0.0.0.0 #ssh服务…...

【Pulling fs layer】Linux使用docker-compose的时候,一直Pulling fs layer

当‌Docker在拉取镜像时卡在“‌pulling fs layer”阶段&#xff0c;可以通过重启Docker服务来解决。 具体步骤如下&#xff1a; 首先&#xff0c;尝试重启Docker服务。可以通过运行以下命令来重启Docker服务&#xff1a; systemctl restart docker 这个命令会重启Docker服务…...

最新保姆级教程使用WildCard开通Claude3升级ChatGPT4.0(2024.8)

如何使用 WildCard 服务注册 Claude3 随着 Claude3 的震撼发布&#xff0c;最强 AI 模型的桂冠已不再由 GPT-4 独揽。Claude3 推出了三个备受瞩目的模型&#xff1a;Claude 3 Haiku、Claude 3 Sonnet 以及 Claude 3 Opus&#xff0c;每个模型都展现了卓越的性能与特色。其中&a…...

layui 乱入前端

功能包含 本实例代码为部分傻瓜框架&#xff0c;插入引用layui。因为样式必须保证跟系统一致&#xff0c;所以大部分功能都是自定义的。代码仅供需要用layui框架&#xff0c;但原项目又不是layui搭建的提供解题思路。代码较为通用 自定义分页功能自定义筛选列功能行内编辑下拉、…...

中国十大顶级哲学家,全球公认的伟大思想家颜廷利:人类为何拥有臀部

人类为何拥有臀部&#xff1f;若众生皆无此部位&#xff0c;又如何能寻得一处真正属于自己的“座位”&#xff1f;在博大精深的中国传统文化中&#xff0c;汉字“座”与“坐”均蕴含“土”字元素。在易经的智慧里&#xff0c;作为五行之一的“土”&#xff0c;象征着人类社会的…...

Threejs中导入GLTF模型克隆后合并

很多场景中会需要同一个模型很多次&#xff0c;但是如果多次加载同一个模型会占用很高的带宽&#xff0c;导致加载很慢&#xff0c;因此就需要使用clone&#xff0c;也就是加载一个模型后&#xff0c;其他需要使用的地方使用clone的方式复制出多个同样的模型&#xff0c;再改变…...

今日arXiv最热大模型论文:北京大学最新综述:视觉大模型中的漏洞与攻防对抗

近年来&#xff0c;视觉语言大模型&#xff08;LVLM&#xff09;在文本转图像、视觉问答等任务中大放异彩&#xff0c;背后离不开海量数据、强大算力和复杂参数的支撑。 但是&#xff01;大模型看似庞大的身躯背后却有一颗脆弱的“心脏”&#xff0c;极易受到攻击。攻击者可以…...

为什么IDEA中使用@Autowired会被警告

我们在使用IDEA编码时&#xff0c;如果用到了Autowired注解注入bean&#xff0c;会发现IDEA会给代码标个波连线&#xff0c;鼠标移动上去&#xff0c;会发下idea提示&#xff1a;不推荐使用Filed injection&#xff0c;这是Spring的核心DI&#xff08;Dendency Injection&#…...

uniapp使用cover-view,使用@click无效

最近要做直播详情页面&#xff0c;用的是第三方直播链接&#xff0c;需要在该页面上放两个按钮&#xff0c;点击按钮需要弹出相关商品及优惠券。类似于抖音直播页面。 第三方链接使用的是web-view进行展示。由于该组件优先级太高&#xff0c;正常的前端组件无法在该页面浮现展…...

Postman 接口测试工具简易使用指南

一、Postman是什么? 我通过kimi问了这样一个问题&#xff0c;它给我的回答是这样的: 它的回答也算比较中规中矩&#xff0c;简单的说postman实际上就是一款接口测试工具&#xff0c;同时它还可以编写对应的测试脚本以及自动生成对应的API文档&#xff0c;结合我的习惯来说&am…...

Move生态:从Aptos和Sui到Starcoin的崛起

区块链技术自诞生以来&#xff0c;已经经历了多个发展阶段和技术迭代。近年来&#xff0c;随着智能合约平台的不断演进&#xff0c;以Move语言为核心的生态系统逐渐崭露头角。Move语言以其安全性、灵活性和高效性吸引了大量开发者和项目方的关注。在Move生态中&#xff0c;Apto…...

MacOS DockerDesktop配置文件daemon.json的位置

如果因为通过可视化页面修改配置错误导致客户端启动不起来&#xff0c;可以去找对应的配置文件通过 vim 修改后重启客户端 cd ~/.docker/...

从光速常数的可变性看宇宙大爆炸的本质

基于先前关于光速本质的讨论&#xff0c;让我们从函数图像看看宇宙大爆炸到底是什么。 先前已经讨论过&#xff0c;在量子尺度上&#xff0c;长度的实际对应物是频率的差异&#xff0c;因为只有频率差异才能在这个尺度上区分相邻时空的两点&#xff0c;而两点之间“差异的大小”…...

敢不敢跟我一起搭建一个Agent!不写一行代码,10分钟搞出你的智能体!纯配置也能真正掌握AI最有潜力的技术?AI圈内人必备技能

说一千道一万&#xff0c;不如实地转一转。学了那么久的AI Agent的概念了&#xff0c;是时候该落地一个Agent看看自己的掌握程度了对不对&#xff0c;我们都理解大脑是自动节能的&#xff0c;但是知识的确需要倒逼自己一把才能真的掌握&#xff0c;不瞒大家说&#xff0c;笔者对…...

vue3和vite双向加持,uni-app性能爆表,众绑是否有计划前端升级到vue3!

uni-app官方已经开始不支持vue2了&#xff0c;而且即将适配的鸿蒙next原生系统&#xff0c;也不支持vue2打包&#xff0c;CRMEB是否有计划跟上潮流呢&#xff0c;如果有会在什么时间呢&#xff0c;有准确的时间表吗&#xff1f;我们非常期待得到答案&#xff01; 新版 uni-app…...

2024年最强网络安全学习路线,详细到直接上清华的教材!

关键词&#xff1a;网络安全入门、渗透测试学习、零基础学安全、网络安全学习路线 首先咱们聊聊&#xff0c;学习网络安全方向通常会有哪些问题前排提示&#xff1a;文末有CSDN官方认证Python入门资料包 &#xff01; 1、打基础时间太长 学基础花费很长时间&#xff0c;光语…...

人脸识别又进化:扫一下 我就知道你得了啥病

未来&#xff0c;扫下你的脸&#xff0c;可能就知道你得啥病了。没在瞎掰&#xff0c;最近的一项研究成果&#xff0c;还真让咱看到了一点眉目。北大的一个研究团队&#xff0c;搞出来一个 AI &#xff0c;说是用热成像仪扫一下脸&#xff0c;就能检测出有没有高血压、糖尿病和…...

yolov8标注细胞、识别边缘、计算面积、灰度值计算

一、数据标注 1. 使用labelme软件标注每个细胞的边界信息&#xff0c;标注结果为JSON格式 2. JSON格式转yolo支持的txt格式 import json import os import glob import os.path as osp此函数用来将labelme软件标注好的数据集转换为yolov5_7.0sege中使用的数据集:param jsonfi…...

WEB前端11-Vue2基础01(项目构建/目录解析/基础案例)

Vue2基础(01) 1.Vue2项目构建 步骤一&#xff1a;安装前端脚手架 npm install -g vue/cli步骤二&#xff1a;创建项目 vue ui步骤三&#xff1a;运行项目 npm run serve步骤四&#xff1a;修改vue相关的属性 DevServer | webpack //修改端口和添加代理 const { defineCo…...

QT--线程

一、线程QThread QThread 类提供不依赖平台的管理线程的方法&#xff0c;如果要设计多线程程序&#xff0c;一般是从 QThread继承定义一个线程类&#xff0c;在自定义线程类里进行任务处理。qt拥有一个GUI线程,该线程阻塞式监控窗体,来自任何用户的操作都会被gui捕获到,并处理…...

通过进程协作显示图像-C#

前言 如果一个软件比较复杂或者某些情况下需要拆解&#xff0c;可以考试将软件分解成两个或多个进程&#xff0c;但常规的消息传递又不能完全够用&#xff0c;使用消息共享内存&#xff0c;实现图像传递&#xff0c;当然性能这个方面我并没有测试&#xff0c;仅是一种解决思路…...

LangChain链与记忆处理[10]:四种基础内置链、四种文档处理链,以及链的自定义和五种运行方式,让你的大模型更加智能

LangChain链与记忆处理[10]:四种基础内置链、四种文档处理链,以及链的自定义和五种运行方式,让你的大模型更加智能 参考文章可以使用国产LLM进行下述项目复现: 初识langchain[1]:Langchain实战教学,利用qwen2.1与GLM-4大模型构建智能解决方案[含Agent、tavily面向AI搜索…...